python闭包中的cell_contents

时间:2014-09-29 07:34:39

标签: python closures

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。

1 个答案:

答案 0 :(得分:10)

  

cell_contents是否在python中调用了闭包?

__closure__是,并且一直是一个单元格元组(甚至在它被称为func_closure时回来)。

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

所以,你想要的可能就是其中之一:

func.__closure__[0].cell_contents

[cell.cell_contents for cell in func.__closure__]

值得注意的是__closure__的详细信息未记录,并且是CPython实现的特定于实现的功能。虽然data model__closure__定义为:

  

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

...它没有说明这些单元格是什么,或者它们有一个名为cell_contents的属性。

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

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

如果你想了解的不仅仅是这个函数返回的内容,你可能想看看它是如何在你最喜欢的解释器中实现的(可能是CPython,因为没有其他主要的解释器支持3.3)。 inspect是旨在提供有用的可读来源的模块之一,因此文档会直接链接到the source code。所以你可以看到它是如何工作的 - 但它基本上是你所期望的;如果__closure__不是None,则只会创建一个dict,将__code__.co_freevars中的每个单元格名称映射到元组中对应的cell.cell_contents

如果你想更深入,我不知道关闭内部的任何好的解释(这将成为一个好的博客文章,我会打赌有人写的...但我能找到的最好的快速谷歌是Michael Foord的Nothing is Private: Python Closures (and ctypes),但如果您了解C和Python C API,CPython的function objectscode objects来源非常易读。您可能还想考虑PyPy 3}},这往往有点复杂,但它全部都在Python中。在PEP 227中还有一个简短的实现说明,它在Python 2.1中添加了闭包,但它没有解释太多。