在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
?它们不是multiply
所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增强提案中了解更多信息:PEP 227-静态嵌套范围。