ホームページ  >  記事  >  バックエンド開発  >  for ループ内の変数のスコープに注意してください

for ループ内の変数のスコープに注意してください

高洛峰
高洛峰オリジナル
2016-10-18 09:16:471878ブラウズ

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 テンプレート言語でコーディングする場合に特に当てはまります。コード エディターにはプロンプトがなく、エラーがどこにあるのかを検出できません。これは私が遭遇した非常に奇妙な例です。なぜ変だと言うかというと、論理的には問題がないからです。

ページ テンプレートでは、ハンドラーがこのテンプレートを呼び出すと、ページ オブジェクトとページ リストという 2 つのオブジェクトが同時に渡されます (ハンドラーから、私は tornado を使用します)。私の注文は次のとおりです:


{{ page.name if page else ''}}

親ページ

{ページ数あたりの%%}

問題はここです。操作中にエラーが発生しました。プロンプトは {{ page.name if page else ''} にあります}

代入前に参照されたエラー ページ。

テンプレート呼び出しプロセス中に、テンプレート言語も Python バイトコードに変換され、一行ずつ解析されて出力されるため、トルネード テンプレート言語のバグであるかどうかはまったくわかりません。

したがって、変数名に注意してください。

要するに、トルネードの例外トレースは非常に不親切だと思います。

Pythonにおける変数のスコープ検索順序: ローカルスコープ(Local) → 現在のスコープが埋め込まれているローカルスコープ(ローカルを囲む) → グローバル/モジュールスコープ(Global) → 組み込みスコープ(Built-in)

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