比兹利第100页提到:
>>>python.__closure__
(<cell at 0x67f50: str object at 0x69230>,)
>>>python.__closure__[0].cell_contents
我的理解是, __closure__
是一个列表但什么是所有这些细胞东西,海峡对象? 这看起来像一个1元的元组?
比兹利第100页提到:
>>>python.__closure__
(<cell at 0x67f50: str object at 0x69230>,)
>>>python.__closure__[0].cell_contents
我的理解是, __closure__
是一个列表但什么是所有这些细胞东西,海峡对象? 这看起来像一个1元的元组?
闭合细胞是指由功能需要的值,但是从周围范围会被执行。
当Python编译一个嵌套函数,它指出它引用但仅在两个嵌套函数和父范围的代码对象父功能(未全局)中所定义的任何变量。 这些是co_freevars
和co_cellvars
属性对__code__
分别的这些功能的对象。
然后,当你真正创建嵌套函数(执行父函数时发生),这些引用然后用于封闭连接到嵌套函数。
函数闭合保持细胞的元组,每一个用于每个自由变量(在一个名为co_freevars
); 细胞对父范围的局部变量,即遵循这些局部变量指向的值特别引用。 这最好用一个例子来说明:
def foo():
def bar():
print(spam)
spam = 'ham'
bar()
spam = 'eggs'
bar()
return bar
b = foo()
b()
在上面的例子中,功能bar
有一个闭合单元,它指向spam
在函数foo
。 细胞遵循的价值spam
。 更重要的是,一旦foo()
完成和bar
返回,细胞继续引用值(字符串eggs
),即使变量spam
中foo
已不存在。
因此,上述代码输出:
>>> b=foo()
ham
eggs
>>> b()
eggs
和b.__closure__[0].cell_contents
是'eggs'
。
请注意, 当关闭取消引用bar()
被调用 ; 关闭并不在这里捕捉值。 这使得当你产生嵌套函数(具有差lambda
表达式或def
语句)引用该循环变量:
def foo():
bar = []
for spam in ('ham', 'eggs', 'salad'):
bar.append(lambda: spam)
return bar
for bar in foo():
print bar()
上述将打印salad
三次连续的,因为所有三个lambda
功能引用spam
变量,而不是值它必然被创建的功能对象时。 由当时for
循环结束, spam
被绑定到'salad'
,那么这3封将解决该值。
这是旧的新的Python 3名func_closure
。
http://docs.python.org/3.0/whatsnew/3.0.html
命名的功能属性
func_X
已更名为使用__X__
形式,功能属性命名空间,用户定义的属性释放了这些名字。 要机智,func_closure
,func_code
,func_defaults
,func_dict
,func_doc
,func_globals
,func_name
已更名为__closure__
,__code__
,__defaults__
,__dict__
,__doc__
,__globals__
,__name__
,分别。
简而言之:
__closure__
是None
或tuple
包含了函数对自由变量绑定细胞。
此外,它是不可写。
参考: http://docs.python.org/ref/types.html
实施例的Python <3(所以我用func_closure
)
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]
输出:
>>>
['I am free', 'I am free too']
如foo
被返回功能bar
,其使用其自己的值x
,但不y
或z
。 于是,他们来到下__closure__
。
>>> def f():
... a = "HELO"
... b = 1.0
... def w(c):
... return a,b,c
... return w
>>> w = f()
>>> w.__closure__
(<cell at 0xa05c4ac: str object at 0x9e91b74>, <cell at 0xa05c3bc: float object at 0xb733dde8>)
>>> w.__closure__[0].cell_contents
'HELO'
>>> w.__closure__[1].cell_contents
1.0
我从来没有见过其他任何地方使用的细胞类型。 这似乎是专门用于举行闭包变量。
当一个嵌套函数( closure
)在python定义为:
外函数使用co_cellvars
要注意在可能由内部函数引用外部函数定义的变量。
内部函数使用co_freevars
要注意在外部函数,这可能会以备后用被引用定义的变量。
例:
# python3
Python 3.4.5 (default, May 29 2017, 15:17:55)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo(n):
... a = 1
... def g(n):
... return a - n
... return g
...
>>> foo.__closure__
>>> foo.__code__.co_freevars
()
>>> foo.__code__.co_cellvars
('a',)
>>> foo(0).__closure__
(<cell at 0x7f2cd98db1c8: int object at 0x7f2cd9847960>,)
>>> foo(0).__closure__[0].cell_contents
1
>>> foo(0).__code__.co_freevars
('a',)
>>> foo(0).__code__.co_cellvars
()