for e in collections: pass
for ループでは、最後のオブジェクト e が常にコンテキスト内に存在します。ループの外側でも、その後の e への参照は依然として有効です。
ここには見落とされがちな問題があります。ループの前に同じ名前のオブジェクトがすでに存在する場合、このオブジェクトは上書きされます。
コード対応 IDE を使用している場合、IDE は変数が「再宣言」されたことを示すメッセージを表示しますが、実行時にエラーは発生しません。
for ループはクロージャではありません。ご覧のとおり、dis モジュールを使用して次のコードを分解できます:
x = 5 for x in range(10): pass print x
コードを test.py ファイルに保存し、 python -m dis test.py
を実行します。C:UsersPatrickDesktop> python -m dis test.py 1 3 3 6 SETUP_LOOP 20 (〜 29)
9 LOAD_NAME 1 (範囲)
12 LOAD_CONST 1 10 : 28 POP_BLOCK
6 >> 29 LOAD_NAME 0 (x)
32 PRINT_ITEM
33 PRINT_NEWLINE
34 LOAD_CONST 2 (なし)
37 RETURN_VALUE
他の言語では、 for ループは Java などのコンテキストにも表示されます。 Java は厳密に型指定された言語であるため、既存の変数を再宣言すると、IDE によってエラーが表示されますが、これはもちろんコンパイルとは異なります。
通常、Pythonプログラミング(おそらくほとんどの動的言語)では、同じ名前の変数が宣言されていても、プログラム内に明らかなエラーがない場合がありますが、一度エラーが発生すると、エラーを見つけるのが困難です。したがって、for ループ内の変数と同じ名前を使用しないでください。
これは、Python テンプレート言語でコーディングする場合に特に当てはまります。コード エディターにはプロンプトがなく、エラーがどこにあるのかを検出できません。これは私が遭遇した非常に奇妙な例です。なぜ変だと言うかというと、論理的には問題がないからです。
{{ page.name if page else ''}}
問題はここです。操作中にエラーが発生しました。プロンプトは {{ page.name if page else ''} にあります}
代入前に参照されたエラー ページ。
テンプレート呼び出しプロセス中に、テンプレート言語も Python バイトコードに変換され、一行ずつ解析されて出力されるため、トルネード テンプレート言語のバグであるかどうかはまったくわかりません。
したがって、変数名に注意してください。 要するに、トルネードの例外トレースは非常に不親切だと思います。 Pythonにおける変数のスコープ検索順序: ローカルスコープ(Local) → 現在のスコープが埋め込まれているローカルスコープ(ローカルを囲む) → グローバル/モジュールスコープ(Global) → 組み込みスコープ(Built-in)