究竟是包含在一个OBJ .__ closure__?(What exactly is contain

2019-07-18 10:29发布

比兹利第100页提到:

>>>python.__closure__
(<cell at 0x67f50: str object at 0x69230>,)
>>>python.__closure__[0].cell_contents

我的理解是, __closure__是一个列表但什么是所有这些细胞东西,海峡对象? 这看起来像一个1元的元组?

Answer 1:

闭合细胞是指由功能需要的值,但是从周围范围会被执行。

当Python编译一个嵌套函数,它指出它引用但仅在两个嵌套函数和父范围的代码对象父功能(未全局)中所定义的任何变量。 这些是co_freevarsco_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 ),即使变量spamfoo已不存在。

因此,上述代码输出:

>>> 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封将解决该值。



Answer 2:

这是旧的新的Python 3名func_closure

http://docs.python.org/3.0/whatsnew/3.0.html

命名的功能属性func_X已更名为使用__X__形式,功能属性命名空间,用户定义的属性释放了这些名字。 要机智, func_closurefunc_codefunc_defaultsfunc_dictfunc_docfunc_globalsfunc_name已更名为__closure____code____defaults____dict____doc____globals____name__ ,分别。

简而言之:

__closure__Nonetuple包含了函数对自由变量绑定细胞。

此外,它是不可写。

参考: 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 ,但不yz 。 于是,他们来到下__closure__



Answer 3:

>>> 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

我从来没有见过其他任何地方使用的细胞类型。 这似乎是专门用于举行闭包变量。



Answer 4:

当一个嵌套函数( 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
()


文章来源: What exactly is contained within a obj.__closure__?