Python代码对象具有属性
除其他语言外,Rust 提供了一个Cell数据类型。谷歌搜索表明它们与闭包有关。
在编程语言实现的上下文中,什么是cell?cell解决了什么问题?
co_cellvars
。PyPy的字节码解释器文档经常使用术语Cell。除其他语言外,Rust 提供了一个Cell数据类型。谷歌搜索表明它们与闭包有关。
在编程语言实现的上下文中,什么是cell?cell解决了什么问题?
co_cellvars
。PyPy的字节码解释器文档经常使用术语Cell。在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
这是如何使用它的方法:
>>> two_thirds = multiplier(2, 3)
>>> two_thirds(7)
4.666666666666667
two_thirds
如何记住n
和d
的值?它们既不是multiplier
函数的参数,也不是在multiply
内部定义的局部变量,也不是全局变量,而且由于multiplier
已经终止,它的局部变量也不存在了,对吗?multiplier
时,解释器注意到multiply
稍后要使用它的局部变量,因此它会记录下它们的值:>>> multiplier.__code__.co_cellvars
('d', 'n')
当调用multiplier
函数时,外部局部变量的值将存储在返回的函数的__closure__
属性中,以cell
对象的元组形式:
>>> two_thirds.__closure__
(<cell at 0x7f7a81282678: int object at 0x88ef60>,
<cell at 0x7f7a81282738: int object at 0x88ef40>)
...使用__code__
对象中的名称作为co_freevars
:
>>> two_thirds.__code__.co_freevars
('d', 'n')
您可以使用单元格的cell_contents
属性获取其内容:>>> {v: c.cell_contents for v, c in zip(
two_thirds.__code__.co_freevars,
two_thirds.__closure__
)}
{'d': 3, 'n': 2}
您可以在引入它们的Python Enhancement Proposal中了解有关闭包及其实现的更多信息:PEP 227 — Statically Nested Scopes。
c.cell_contents = 5
。更一般的情况是:func.__closure__[func.__code__.co_freevars.index(name)].cell_contents = value
。 - undefined
Cell
只是一种绕过继承的不可变性的方式,以便您可以修改数据,尽管对其具有不可变引用。这与Python的含义相当不同。 “Cell”是一个非常通用的术语,你知道的。 - Chris Morgan