入れ子関数とローカル変数へのアクセス
Python では、入れ子関数は、それを囲んでいるスコープからローカル変数にアクセスできます。ただし、このアクセスのタイミングは直観に反している可能性があります。
次のコード スニペットを考えてみましょう:
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()
メアリーが各動物を撫でるという期待される出力を取得する代わりに、出力には「メアリーがペットを撫でる」と表示されます。 3 匹の動物すべてに対して「猫」。この動作は、ネストされた関数 pet_function が定義時ではなく実行時にローカル変数ケージを検索するために発生します。
関数 get_petters が呼び出されると、ローカル変数ケージが各動物に順次割り当てられます。ループ内で。ただし、関数の終わりまでに、cage には最後の値 ('cat') が含まれます。 get_petters によって返される関数が呼び出されると、それらはすべて、値 'cat' を持つ同じケージ変数にアクセスします。
この問題に対処するには、次のようなさまざまな手法を使用できます。
バインドされたケージで部分関数を使用する変数:
from functools import partial def pet_function(cage): print "Mary pets the " + cage.animal + "." yield (animal, partial(gotimes, partial(pet_function, cage=cage)))
ネストされた関数の新しいスコープの作成:
def scoped_cage(cage): def pet_function(): print "Mary pets the " + cage.animal + "." return pet_function yield (animal, partial(gotimes, scoped_cage(cage)))
変数をデフォルト値としてバインドキーワードパラメータ:
def pet_function(cage=cage): print "Mary pets the " + cage.animal + "." yield (animal, partial(gotimes, pet_function))
以上が入れ子になった Python 関数が定義時ではなく実行時に変数にアクセスするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。