解释器或编译器上下文中的单元是什么?

Wil*_*hes 8 python compiler-construction closures interpreter rust

Python代码对象具有一个属性co_cellvars.PyPy的字节码解释器的文档通常使用术语Cell.

在其他语言中,Rust 提供了Cell数据类型.谷歌搜索表明他们以某种方式与封闭有关.

在编程语言实现的上下文中,什么是单元?细胞解决了什么问题?

Zer*_*eus 12

在Python中,cell对象是用于存储自由变量一个的关闭.

假设您想要一个总是返回其参数的特定部分的函数.您可以使用闭包来实现此目的:

def multiplier(n, d):
    """Return a function that multiplies its argument by n/d."""
    def multiply(x):
        """Multiply x by n/d."""
        return x * n / d
    return multiply
Run Code Online (Sandbox Code Playgroud)

以下是如何使用它:

>>> two_thirds = multiplier(2, 3)
>>> two_thirds(7)
4.666666666666667
Run Code Online (Sandbox Code Playgroud)

如何two_thirds记住的价值观nd?它们不是定义multiply函数的参数multiplier,它们不是内部定义的局部变量multiply,它们不是全局变量,并且由于multiplier已经终止,它的局部变量不再存在,对吧?

会发生什么事情,当multiplier编译时,解释器会注意到multiply以后想要使用它的局部变量,所以它会记下它们:

>>> multiplier.__code__.co_cellvars
('d', 'n')
Run Code Online (Sandbox Code Playgroud)

然后在multiplier调用时,那些外部局部变量的值存储在返回函数的__closure__属性中,作为cell对象的元组:

>>> two_thirds.__closure__
(<cell at 0x7f7a81282678: int object at 0x88ef60>,
 <cell at 0x7f7a81282738: int object at 0x88ef40>)
Run Code Online (Sandbox Code Playgroud)

......他们在__code__对象中的名字如下co_freevars:

>>> two_thirds.__code__.co_freevars
('d', 'n')
Run Code Online (Sandbox Code Playgroud)

您可以使用其cell_contents属性获取单元格的内容:

>>> {v: c.cell_contents for v, c in zip(
        two_thirds.__code__.co_freevars,
        two_thirds.__closure__
)}
{'d': 3, 'n': 2}
Run Code Online (Sandbox Code Playgroud)

您可以在Python Enhancement Proposal中阅读有关闭包及其实现的更多信息,该建议引入了它们:PEP 227 - 静态嵌套作用域.