ループまたは内包表記で関数を作成する場合の遅延バインディングについて
ループ内で関数を作成しようとすると、次のような状況が発生する可能性があります。すべての関数は、異なる出力を期待しているにもかかわらず、同じ値を返します。この動作は、変数の値が実行時に解決される遅延バインディングが原因で発生します。
Python の遅延バインディング
Python では、関数とラムダは実行時のデフォルトのバインド変数。これは、関数が呼び出されたときに、その中で使用されている変数が検索されることを意味します。ループでは、ループ反復子 i は後で解決され、その時点までにループ後の i の最終値を参照します。
たとえば、次のコード スニペットでは:
functions = [] for i in range(3): def f(): return i functions.append(f)
関数リスト内のすべての関数は、同じ i の値を参照します。これは、ループ終了後の 2 です。
早期の強制バインディング
この問題を解決するには、早期バインディングを強制する必要があります。これにより、関数定義時に i の値が確実にバインドされます。これを行う 1 つの方法は、以下に示すように、引数のデフォルト値を使用することです。
functions = [] for i in range(3): def f(i=i): return i functions.append(f)
i 引数にデフォルト値を指定すると、早期バインディングが強制されます。 f 関数に渡される i の値は、関数の実行時ではなく、関数の定義時に解決されます。
関数ファクトリの使用
別のアプローチは次のとおりです。必要なバインディングを持つ関数を作成する関数ファクトリを使用します。これには、バインドする変数を受け取り、事前にバインドされた変数を含むネストされた関数を返す追加関数の作成が含まれます。
def make_f(i): def f(): return i return f
ループ内で、 f = make_f(i) を使用して適切な初期バインディングを使用して関数を実行します。
以上がPython ループ内の関数がすべて同じ値を返すのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。