ホームページ > バックエンド開発 > Python チュートリアル > クロージャは入れ子になった Python 関数のローカル変数アクセスにどのような影響を与えますか?

クロージャは入れ子になった Python 関数のローカル変数アクセスにどのような影響を与えますか?

Linda Hamilton
リリース: 2024-12-18 09:29:18
オリジナル
407 人が閲覧しました

How Do Closures Affect Local Variable Access in Nested Python Functions?

入れ子関数のローカル変数: クロージャとルックアップの物語

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 サイトの他の関連記事を参照してください。

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