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

Python の入れ子関数がループ変数の最後の値にのみアクセスするのはなぜですか?

Patricia Arquette
リリース: 2024-12-18 00:47:13
オリジナル
473 人が閲覧しました

Why does my nested function in Python only access the last value of a loop variable?

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

入れ子関数は、コードを整理し、より広いコンテキスト内で機能をカプセル化する便利な方法を提供します。ただし、ネストされたスコープ内で変数がどのように処理されるかを理解すると、開発者は困惑することがよくあります。

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

class Cage(object):
    def __init__(self, animal):
        self.animal = animal

def get_petters():
    for animal in ['cow', 'dog', 'cat']:
        cage = Cage(animal)

        def pet_function():
            print("Mary pets the " + cage.animal + ".")

        yield (animal, cage.animal)
ログイン後にコピー

この例では、ジェネレーター関数 get_petters() が動物のリスト。動物ごとに Cage オブジェクトを作成し、動物の名前とケージのローカルへのアクセスを試みる入れ子関数を含むタプルを生成します。 variable.

このコードを実行すると、ケージ変数の 3 つの異なるインスタンスに対応する 3 つの異なる動物が出力されることが期待されるかもしれません。ただし、出力では「Marypets the cat」のみが繰り返し生成されます。

クロージャの動作を理解する

問題の核心は、Python におけるクロージャの性質にあります。ネストされた関数が定義されると、それを囲んでいるスコープ内の変数への参照がキャプチャされます。提供されたコードでは、pet_function は get_petters() 関数内にネストされているため、ケージ変数にアクセスできます。

ただし、この参照は関数定義時には確立されません。代わりに、関数の実行時に発生します。ネストされた関数が実行されるまでに、動物のリストを反復処理するときに、ケージ変数にはすでに値「cat」が割り当てられています。

解決策

この問題を解決するには、次の方法があります。いくつかのアプローチを採用します。

1.部分関数:

部分関数は、既存の関数をラップし、その引数の一部を事前設定された値で初期化する呼び出し可能関数です。この場合、 functools.partial() を使用して、ケージ変数を適切なコンテキストにバインドする部分ペット関数を作成できます:

def pet_function(cage=None):
    print("Mary pets the " + cage.animal + ".")

yield (animal, partial(pet_function, cage=cage))
ログイン後にコピー

2。新しいスコープの作成:

もう 1 つのオプションは、ケージ変数が常にローカルで正しい値にバインドされるようにする、ネストされたスコープ内でペット関数を定義することです:

def scoped_cage(cage=None):
    def pet_function():
        print("Mary pets the " + cage.animal + ".")
    return pet_function

yield (animal, partial(pet_function, cage))
ログイン後にコピー

3.デフォルトのキーワード パラメータ:

ケージ変数をデフォルトのキーワード引数としてペット関数に渡すこともできます:

def pet_function(cage=cage):
    print("Mary pets the " + cage.animal + ".")

yield (animal, partial(pet_function))
ログイン後にコピー

これらの手法に従うことで、ネストされた関数は予期されるローカル変数を使用して動作するため、予期しない副作用が排除され、コードの明瞭さが維持されます。

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

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