入れ子関数が親関数のローカル変数の最終値にのみアクセスするのはなぜですか?
入れ子関数のローカル変数
入れ子関数は、親関数内に特定の機能をカプセル化する便利な手段を提供します。ただし、クロージャーの動作により、アクセスしやすさとローカル変数の値に関していくつかの複雑な問題が発生する可能性があります。
問題:
次のコード スニペットを考えてみましょう:
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 サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











fiddlereveryversings for the-middleの測定値を使用するときに検出されないようにする方法

10時間以内にコンピューター初心者プログラミングの基本を教える方法は?コンピューター初心者にプログラミングの知識を教えるのに10時間しかない場合、何を教えることを選びますか...

Pythonasyncioについて...

Investing.comの反クラウリング戦略を理解する多くの人々は、Investing.com(https://cn.investing.com/news/latest-news)からのニュースデータをクロールしようとします。

Python 3.6のピクルスファイルの読み込みエラー:modulenotfounderror:nomodulenamed ...

SCAPYクローラーを使用するときにパイプラインファイルを作成できない理由についての議論は、SCAPYクローラーを学習して永続的なデータストレージに使用するときに、パイプラインファイルに遭遇する可能性があります...
