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 ) を参照します。eggsspamfoo
したがって、上記のコードは次を出力します。
>>> 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 つのクロージャすべてがその値に解決されます。lambdaspamforspam'salad'
これは、古いの新しいPython3の名前ですfunc_closure。
http://docs.python.org/3.0/whatsnew/3.0.html
指定された関数属性は、フォーム
func_Xを使用するように名前が変更され__X__、ユーザー定義属性の関数属性名前空間でこれらの名前が解放されました。ウィットに、、、、、、、、は、func_closureそれぞれ、、、、、、、、に名前が変更されました。func_codefunc_defaultsfunc_dictfunc_docfunc_globalsfunc_name__closure____code____defaults____dict____doc____globals____name__
一言で言えば:
__closure__関数の自由変数のバインディングを含むセルのまたはNonea 。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いる関数を返していますが、またはは返していません。だから、彼らは下に入る。barxyz__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
他の場所で使用されている細胞型を見たことがありません。クロージャー変数を保持する目的で構築されているようです。