没有区别,因为没有闭合函数,不是真的。有closures,但这一术语指的是在外部和内部范围中保存变量的技术。只剩下嵌套函数。在
嵌套函数只是在另一个函数内部定义的函数:def outer():
def inner():
# ...
# ...
当outer()定义了一个inner()然后也使用的名称,则该变量名称为闭包单元,存储在inner的闭包环境中:
^{pr2}$
这里variable_in_outer是由inner()在上闭合的,因此创建了一个闭包。如果inner()的生命周期超过了outer(因为inner被返回给outer()的调用者),那么你不能像处理其他局部变量那样只清理variable_in_outer。another_variable是outer中没有被嵌套函数使用的任何其他变量;它只是另一个局部变量,在outer()结束时被清除。在
所以创建了一个闭包来保持变量的活性,直到inner()也消失了。闭包包含variable_in_outer闭包单元,以及任何其他此类闭包变量,只要{}需要它们。在
在编译时决定关闭哪些名称。您可以通过函数对象上的__closure__属性来内省闭包,闭包单元是闭包单元的元组,每个闭包单元都有一个cell_contents属性,允许您访问变量的当前值。如果没有闭包,__closure__被设置为None:>>> def outer():
... variable_in_outer = 42
... another_variable = 81
... def inner():
... return variable_in_outer
... return inner # return the inner function object
...
>>> nested = outer()
>>> nested
.inner at 0x106a46c80>
>>> nested.__closure__
(,)
>>> nested.__closure__[0].cell_contents
42
>>> outer.__closure__ is None # outer has no closed-over variables.
True
因为编译器决定什么是闭包,什么不是闭包,所以您可以反省代码对象,以查看闭包使用了哪些名称:>>> outer.__code__.co_cellvars
('variable_in_outer',)
>>> outer.__code__.co_consts[3] # code object used to create `inner` functions
", line 3>
>>> outer.__code__.co_consts[3].co_freevars
('variable_in_outer',)
co_cellvars是变为闭包的变量名,co_freevars是使用这些闭包的引用。在