入れ子関数のローカル変数: クロージャとルックアップの物語
Python では、入れ子関数内で定義されたローカル変数は周囲の関数と相互作用できます。範囲。この相互作用を理解するために、動作を強調表示するコード スニペットを詳しく見てみましょう。
from functools import partial class Cage(object): def __init__(self, animal): self.animal = animal def gotimes(do_the_petting): do_the_petting() def get_petters(): for animal in ['cow', 'dog', 'cat']: cage = Cage(animal) def pet_function(): print "Mary pets the " + cage.animal + "." yield (animal, partial(gotimes, pet_function)) funs = list(get_petters()) for name, f in funs: print name + ":", f()
Ambiguous Assignment
このコードを実行すると、予期しない結果が生成されます。「メアリー ペット3匹の動物(「牛」「犬」「猫」)すべてに「the cat」がプリントされています。これは、入れ子関数 pet_function 内のローカル変数ケージがクロージャ セルとしてキャプチャされるためです。
Closure Cell
入れ子関数が作成されると、ローカル変数が参照されます。親スコープ内の変数。この場合、cage は pet_function 内の唯一の自由変数であり、クロージャ セルにバインドされています。このセルを使用すると、親関数が戻った後でも関数が外側のスコープの変数にアクセスできるようになります。
スコープの解決
ただし、ネストされた関数が実行されるときに問題が発生します。ケージの値は、定義ではなく、周囲のスコープ実行時にで検索されます。この場合、関数が呼び出されるまでに、周囲のスコープ内のケージ変数には、最終値として「cat」がすでに割り当てられています。
回避策
このあいまいさを解決するには、クロージャを破って、入れ子になった関数が周囲のスコープに直接アクセスできないようにする必要があります。以下にいくつかの回避策を示します:
これらの回避策を使用すると、ネストされた関数は正しいローカル変数にアクセスできるため、コード内のあいまいさを回避できます。
以上がクロージャは入れ子になった Python 関数のローカル変数アクセスにどのような影響を与えますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。