The function attributes named func_X have been renamed to use the __X__ form, freeing up these names in the function attribute namespace for user-defined attributes. To wit, func_closure, func_code, func_defaults, func_dict, func_doc, func_globals, func_name were renamed to __closure__, __code__, __defaults__, __dict__, __doc__, __globals__, __name__, respectively.
def foo():
x = "I am used"
y = "I am free"
z = "I am free too"
def bar(x):
return x, y, z
return bar
c = foo().func_closure
print [i.cell_contents for i in c]
闭包单元格指的是函数所需的值,但这些值取自周围的范围。
当Python编译嵌套函数时,它会注意到它引用的任何变量,但这些变量仅在嵌套函数和父作用域的代码对象中的父函数(而不是全局)中定义。这些分别是这些函数的
__code__
对象上的co_freevars
和co_cellvars
属性。然后,当实际创建嵌套函数(在执行父函数时发生)时,这些引用将用于将闭包附加到嵌套函数。
函数闭包包含一个单元元组,每个单元对应一个自由变量(在
co_freevars
中命名);单元是对父作用域的局部变量的特殊引用,它遵循这些局部变量指向的值。这最好用一个例子来说明:在上面的例子中,函数
bar
有一个闭包单元格,它指向函数foo
中的spam
。单元格遵循spam
的值。更重要的是,一旦foo()
完成并返回bar
,即使foo
中的变量spam
不再存在,单元格仍继续引用该值(字符串eggs
)。因此,上述代码输出:
而
b.__closure__[0].cell_contents
就是'eggs'
。注意,当
bar()
被调用时,闭包会被取消引用;闭包不会在这里捕获值。当您生成引用循环变量的嵌套函数(使用lambda
表达式或def
语句)时,这会有所不同:上面将连续打印
salad
三次,因为所有三个lambda
函数都引用spam
变量,而不是创建函数对象时绑定到的值。当for
循环结束时,spam
已绑定到'salad'
,因此所有三个闭包都将解析为该值。它是旧的
func_closure
的新Python 3名称。http://docs.python.org/3.0/whatsnew/3.0.html
简而言之:
__closure__
是包含函数自由变量绑定的None
或tuple
细胞。而且,它是不可写的。
引用:http://docs.python.org/ref/types.html
示例Python<;3(因此我正在使用
func_closure
)输出:
因为
foo
返回的是函数bar
,它使用自己的值x
,而不是y
或z
。所以,它们属于__closure__
。我从未见过在其他地方使用的单元格类型。它似乎是专门为保存闭包变量而构建的。
相关问题 更多 >
编程相关推荐