Beazley pg 100 は次のように述べています。
>>>python.__closure__
(<cell at 0x67f50: str object at 0x69230>,)
>>>python.__closure__[0].cell_contents
私の理解では、それ__closure__
はリストですが、このセルのものと str オブジェクトは何ですか?? 1 項タプルのように見えますか?
Beazley pg 100 は次のように述べています。
>>>python.__closure__
(<cell at 0x67f50: str object at 0x69230>,)
>>>python.__closure__[0].cell_contents
私の理解では、それ__closure__
はリストですが、このセルのものと str オブジェクトは何ですか?? 1 項タプルのように見えますか?
クロージャ セルは、関数に必要な値を参照しますが、周囲のスコープから取得されます。
Python がネストされた関数をコンパイルするとき、それが参照するが、ネストされた関数と親スコープの両方のコード オブジェクト内の親関数 (グローバルではない) でのみ定義されている変数を記録します。これらは、それぞれこれらの関数のオブジェクトのco_freevars
およびco_cellvars
属性です。__code__
次に、ネストされた関数を実際に作成すると (これは親関数が実行されたときに発生します)、それらの参照を使用して、ネストされた関数にクロージャーをアタッチします。
関数クロージャはセルのタプルを保持し、各自由変数 ( で名前が付けられていますco_freevars
) ごとに 1 つずつです。セルは、親スコープのローカル変数への特別な参照であり、ローカル変数が指す値に従います。これは、次の例で最もよく説明されています。
def foo():
def bar():
print(spam)
spam = 'ham'
bar()
spam = 'eggs'
bar()
return bar
b = foo()
b()
上記の例では、関数bar
には 1 つのクロージャ セルがあり、関数内で を指してspam
いますfoo
。セルは の値に従いますspam
。さらに重要なことは、 がfoo()
完了して返されると、セル内の変数が存在しなくなってもbar
、セルは引き続き値 ( string ) を参照します。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()
上記は、関数オブジェクトが作成されたときにバインドされた値ではなく、 3 つの関数salad
すべてが変数を参照するため、3 回続けて出力されます。ループが終了するまでにはにバインドされているため、3 つのクロージャすべてがその値に解決されます。lambda
spam
for
spam
'salad'
これは、古いの新しいPython3の名前です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
a 。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
他の場所で使用されている細胞型を見たことがありません。クロージャー変数を保持する目的で構築されているようです。