ホームページ  >  記事  >  バックエンド開発  >  Python 関数クロージャを使用する際に注意すべき問題を説明する例

Python 関数クロージャを使用する際に注意すべき問題を説明する例

WBOY
WBOYオリジナル
2016-07-21 14:53:191338ブラウズ

昨日、暗闇の中で陽の指の力の10%でキーボードをつついてコーディングしていたとき、たまたま質問を受けて、私の良い仕事を奪われそうになりました。古代の力が漏れて人々に衝撃を与えました。あまりナンセンスではありませんが、栗から始めましょう(問題を説明するためだけに簡略化したものです):

リーリー

再試行デコレータのシンプルなバージョン。必要な変数はクロージャによって完全にキャプチャされ、ロジックは非常にシンプルかつ明確です。質問者によると、ロジックは正常のようですが、変数 retry_times が見つからない (未解決の参照) というエラー メッセージが報告され続けました。

そうです、注意深くチェックしてください。これはスコアリングの質問です。不変型のデータが操作される場合、クロージャ (retry_times、retry_wait) によってキャプチャされた変数は、クロージャによって参照される再試行関数のローカル変数と同等です。 Wrap_function のローカル関数では、新しいローカル変数が生成されますが、新しく生成されたローカル変数 retry_times は使用時に初期化される時間がないため、逆に変数が見つからないというメッセージが表示されます。よく使われました。

Python はダックタイピング プログラミング言語です。警告がある場合でも、できるだけ単純な関数を作成し、wrap_function ロジックにブレークポイントを置き、それぞれの値を確認します。変数を参照すると、問題をすぐに見つけることができます (直接実行すると、「UnboundLocalError: local variable 'retry_attempts' Referenced before assigning」というエラーも表示されます。少なくとも警告メッセージよりは便利です):

リーリー

この種の問題は、変更可能なコンテナーを使用して、使用したい不変型のデータをラップするだけで簡単に解決できます。たとえば、C#.net では、クロージャが検出されると、難読化された名前のクラスが自動的に作成されます。生成され、取得される値はクラスの属性として保存されるため、使用時に簡単に取得できるようになります。有名な Lao Zhao には、このトピックに関連していると思われる Lazy Evaluation に関する記事があるようです):

リーリー

出力:

リーリー

dict でラップした後、プログラムが期待どおりに正常に動作することが出力からわかります。実際、関数のクロージャの値からも再度確認できます。

リーリー
私がエンディング、PEACE!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。