Python在哪里存储函数闭包的名称绑定? [英] Where does Python store the name binding of function closure?
问题描述
所以最近我了解了函数闭包的概念。
So recently I understand the concept of function closure.
def outer():
somevar = []
assert "somevar" in locals() and not "somevar" in globals()
def inner():
assert "somevar" in locals() and not "somevar" in globals()
somevar.append(5)
return somevar
return inner
function = outer()
somevar_returned = function()
assert id(somevar_returned) == id(function.func_closure[0].cell_contents)
可以理解,函数关闭的目的是保持对对象的主动引用,以避免对该对象进行垃圾回收。这就是为什么以下方法可以正常工作的原因:
As much as I understand, the objective of function closure is to keep an active reference to the object, in order to avoid garbage collection of this object. This is why the following works fine :
del outer
somevar_returned_2 = function()
assert id(somevar_returned) == id(function.func_closure[0].cell_contents)
assert id(somevar_returned) == id(somevar_returned_2)
事情是(据我所知)在执行 inner
函数之前,Python会重建本地变量字典。该词典将包含:
The thing is (always as much as I understood) before the execution of the inner
function, Python rebuild the locals variables dictionary. This dictionary will contains :
- 与函数的单元格内容关联的闭包名称
- 函数的参数与它们的默认值或给定参数相关联的名称(并且它可以覆盖先前的名称)
问题是Python在哪里存储名称绑定的关闭?我在任何地方都找不到它。
The question is where do Python store the name binding of the closure ? I can't find it anywhere.
注意:函数的属性:
>>> print "\n".join("%-16s : %s" % (e, getattr(function, e)) for e in dir(function) if not e.startswith("_") and e != "func_globals")
func_closure : (<cell at 0x2b919f6bc050: list object at [...]>,)
func_code : <code object inner at [...], file "<stdin>", line 4>
func_defaults : None
func_dict : {}
func_doc : None
func_name : inner
推荐答案
这取决于python实现。我假设您的意思是CPython。
__ code __
(或 func_code
)具有 co_freevars
属性,该属性包含所有非局部变量的名称(它们被称为免费vars,就好像python函数是逻辑上的
The __code__
(or func_code
) has a co_freevars
attribute that contains the name of all non-local variables (they are called "free vars" as if a python function was a logical formula where the arguments and local variables are quantified variables)
从这些各种属性中,您可以获取从本地和非本地名称到单元格的映射。
From these various attribute you can obtain a mapping from local and non-local names to cells.
In [35]: function.__code__.co_freevars
Out[35]: ('somevar',)
co_varnames
属性列出了所有本地定义的名称:
The co_varnames
attribute lists all locally define names:
In [36]: function.__code__.co_varnames
Out[36]: ()
In [37]: def outer():
...: somevar = ["stackoverflow"]
...: def inner():
...: x = 1
...: somevar.append(5)
...: return somevar
...: return inner
...:
...: function = outer()
In [38]: function.__code__.co_varnames
Out[38]: ('x',)
co_cellvars
表示 inner 函数使用哪些本地名称:
While co_cellvars
says which local names are used by inner functions:
In [43]: outer.__code__.co_cellvars
Out[43]: ('somevar',)
所有闭包函数均具有 __ closure __
属性。此属性返回单元格对象的元组。并且单元格对象具有 cell_contents
属性,该属性存储变量的值。
All closure functions have __closure__
attribute. This attribute returns a tuple of cell objects. And The cell object has cell_contents
attribute which stores the value of variable.
In [44]: function.__closure__
Out[44]: (<cell at 0x7f4e06b002b8: list object at 0x7f4e06b522c8>,)
In [45]: function.__closure__[0].cell_contents
Out[45]: ["stackoverflow"]
这篇关于Python在哪里存储函数闭包的名称绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!