python闭包中的cell_contents


问题内容

cell_contents要求在python中关闭吗?我了解func_closure无法正常__closure__工作。

func.__closure__.cell_contents
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'cell_contents'

我正在使用Python 3.4.1。


问题答案:

cell_contents要求在python中关闭吗?

__closure__是并且一直是一个元组元组(甚至在调用时也是如此func_closure)。

每个单元仍然有一个cell_contents成员。但是,元组当然不会。

因此,您想要的可能是以下之一:

func.__closure__[0].cell_contents

[cell.cell_contents for cell in func.__closure__]

值得注意的是,__closure__CPython的详细信息尚未记录,并且是CPython实现的特定于实现的功能。而数据模型定义__closure__为:

None 或包含该函数的自由变量的绑定的单元格元组。

……它没有说明这些单元格是什么,也没有说它们具有名为的属性cell_contents

但是在3.3+版本中,有一种记录的方式来获取此信息inspect.getclosurevars

>>> inspect.getclosurevars(func)
ClosureVars(nonlocals={'i': 1}, globals={}, builtins={}, unbound=set())

如果您想了解更多该函数返回的信息,则可能需要查看如何在您喜欢的解释器中实现它(可能是CPython,因为其他主要解释器都不支持3.3)。inspect是旨在提供有用的可读源的那些模块之一,因此docs直接链接到源代码。因此,您可以了解它的工作原理,但基本上就是您所期望的;如果__closure__不是None,它只是创建一个字典,将每个单元格名称映射__code__.co_freevarscell.cell_contents元组中对应的单元格。

如果您想更深入一点,我不知道对闭包的内部有任何好的解释(那将是一篇不错的博客文章,我敢打赌有人写过一个……但是我可以在快速的google中找到最好的解释)是Michael
Foord的《没有什么不私有的:Python闭包(和ctypes)》,但是如果您了解C和Python C API
,则CPython的函数对象代码对象的源就很容易理解了,您可能还想考虑一下PyPy,有点复杂,但这全在Python中了。PEP227中还有一个简短的实现说明,该说明在Python
2.1中添加了闭包,但并没有太多解释。