ホームページ > バックエンド開発 > Python チュートリアル > 入れ子関数が親関数のローカル変数の最終値にのみアクセスするのはなぜですか?

入れ子関数が親関数のローカル変数の最終値にのみアクセスするのはなぜですか?

Barbara Streisand
リリース: 2024-12-16 12:49:14
オリジナル
472 人が閲覧しました

Why Does My Nested Function Only Access the Final Value of a Local Variable in Its Parent Function?

入れ子関数のローカル変数

入れ子関数は、親関数内に特定の機能をカプセル化する便利な手段を提供します。ただし、クロージャーの動作により、アクセスしやすさとローカル変数の値に関していくつかの複雑な問題が発生する可能性があります。

問題:

次のコード スニペットを考えてみましょう:

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())
ログイン後にコピー

望ましい動作は、それぞれに 3 つの異なる動物 (「牛」、「犬」、「猫」) を出力することです。反復。ただし、プログラムはすべての反復で「cat」のみを出力します。この動作は、ローカル変数ケージが入れ子関数に関連付けられているという期待と矛盾します。

答え:

誤解は、入れ子関数が参照を格納するという仮定にあります。定義時に親スコープのローカル変数に追加されます。実際には、ネストされた関数は、実行時にのみ親スコープから変数を検索します。

この特定の例では、pet_function 用に作成されたクロージャーは、get_petters 関数からのケージ変数にインデックスを付けます。 pet_function が呼び出されると、クロージャにアクセスしてケージの値を取得します。ただし、その時点で get_petters 関数は完了しており、ケージ変数の最終値は「cat」になります。したがって、pet_function バリエーションへの後続の呼び出しはすべて、値 'cat' を返します。

回避策:

この問題を解決するには、さまざまな手法を使用して、ネストされた関数は、ケージの正しい値にアクセスします:

  • Partial function: functools.partial を使用して、ケージの固定値を持つ新しい関数を作成します。
  • スコープ関数: ループ内に新しい関数を作成して、各関数の一意のスコープを確保します。 pet_function のインスタンス。
  • デフォルトのパラメータ値: ケージをデフォルトのパラメータ値として渡します。 pet_function.

これらのアプローチのいずれかを採用することで、入れ子関数が反復ごとに意図したローカル変数に確実にアクセスできるようになります。

以上が入れ子関数が親関数のローカル変数の最終値にのみアクセスするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート