python 中的 cell_contents 对闭包的调用是否发生了变化?
__closure__
是并且一直是一个单元元组(甚至在它被称为func_closure
).
每个细胞仍然有一个cell_contents
成员。但元组当然不会。
所以,您想要的可能是其中之一:
func.__closure__[0].cell_contents
[cell.cell_contents for cell in func.__closure__]
值得注意的是,其中的细节__closure__
未记录并且是 CPython 实现的特定于实现的功能。虽然数据模型定义__closure__
as:
None
或包含函数自由变量绑定的单元元组。
...它没有说明这些单元格是什么,或者它们有一个名为cell_contents
.
但在 3.3+ 中,有一种记录在案的方法可以获取此信息,inspect.getclosurevars:
>>> inspect.getclosurevars(func)
ClosureVars(nonlocals={'i': 1}, globals={}, builtins={}, unbound=set())
如果您想了解的不仅仅是这个函数返回的内容,您可能想看看它是如何在您最喜欢的解释器中实现的(可能是 CPython,因为其他主要解释器尚不支持 3.3)。inspect
是那些旨在提供有用的、可读的源代码的模块之一,因此文档直接链接到源代码。所以你可以看到它是如何工作的——但这基本上就是你所期望的;如果__closure__
isn't None
,它只是创建一个映射每个单元格名称的字典__code__.co_freevars
到对应的cell.cell_contents
来自元组。
如果你想更深入,我不知道闭包内部有什么好的解释(这将是一篇很好的博客文章,我敢打赌有人写过......但我可以在快速谷歌中找到最好的解释)是迈克尔·福德的没有什么是私有的:Python 闭包(和 ctypes),但是 CPython 的源代码函数对象 and 代码对象如果您了解 C 和 Python C API,那么本书的可读性非常好。您可能还想考虑查看PyPy,这往往有点复杂,但都是用 Python 编写的。还有一个简短的实施说明PEP 227,它在Python 2.1中添加了闭包,但并没有解释太多。