web-dev-qa-db-ja.com

ifステートメントで初期化された変数のスコープは何ですか?

私はPythonが初めてなので、これはおそらく簡単なスコープの質問です。 Pythonファイル(モジュール)の次のコードは、少し混乱させます:

if __== '__main__':
    x = 1

print x

私が働いた他の言語では、x変数はifステートメントに対してローカルであり、その外部には存在しないため、このコードは例外をスローします。しかし、このコードは実行され、1を出力します。誰でもこの動作を説明できますか?モジュール内で作成されたすべての変数は、モジュール全体でグローバル/使用可能ですか?

234
froadie

Python変数のスコープは、それらが割り当てられている最も内側の関数、クラス、またはモジュールです。 ifwhileブロックなどの制御ブロックはカウントされないため、if内で割り当てられた変数は、引き続き関数、クラス、またはモジュールにスコープされます。

(ジェネレーター式またはlist/set/dict内包表記do count、ラムダ式で定義された暗黙関数。代入ステートメントをこれらのいずれかに詰め込むことはできませんが、ラムダパラメーターとfor句のターゲットは暗黙的な割り当てです。

247
Luke Maurer

はい、それらは同じ「ローカルスコープ」にあり、実際にはこのようなコードはPythonで一般的です。

if condition:
  x = 'something'
else:
  x = 'something else'

use(x)

xは、たとえばCやJavaの場合のように、条件の前に宣言または初期化されないことに注意してください。

つまり、Pythonにはブロックレベルのスコープがありません。ただし、次のような例に注意してください

if False:
    x = 3
print(x)

明らかにNameError例外が発生します。

79
Eli Bendersky

pythonのスコープは次の順序に従います。

  • ローカルスコープを検索する

  • 含まれる関数のスコープを検索します

  • グローバルスコープを検索する

  • ビルトインを検索する

ソース

ifおよびその他のループ/分岐構造はリストされていないことに注意してください-クラス、関数、およびモジュールのみがPythonでスコープを提供します。したがって、ifブロックで宣言されたものは、 。変数はコンパイル時にチェックされないため、他の言語は例外をスローします。 Pythonでは、必要なときに変数が存在する限り、例外はスローされません。

35
Daniel G

Eliが言ったように、Pythonは変数宣言を必要としません。 Cでは次のように言います。

int x;
if(something)
    x = 1;
else
    x = 2;

ただし、Python宣言は暗黙的であるため、xに割り当てると自動的に宣言されます。 Pythonは動的に型指定されるためです-使用されるパスによっては、変数が宣言されずに使用される可能性があるため、静的に型指定された言語では機能しません。これはコンパイル時に静的に型付けされた言語でキャッチされますが、動的に型付けされた言語では許可されます。

静的に型付けされた言語が、この問題のためにifステートメントの外部で変数を宣言する必要があることに限定されている唯一の理由。ダイナミックを受け入れます!

9
Skilldrick

Cなどの言語とは異なり、Python変数は、最も内側の「ブロック」だけでなく、関数(またはクラス、モジュール)全体のスコープ内にあります。 Pythonで変数を宣言する必要がないことを除いて、関数(またはクラス、モジュール)の先頭でint xを宣言したかのようです。

変数xの存在は、実行時、つまりprint xステートメントに到達したときにのみチェックされることに注意してください。 __name__"__main__"と等しくなかった場合、例外NameError: name 'x' is not definedが発生します。

9
Paul Stephenson

はい。 forスコープにも当てはまります。もちろん機能しません。

あなたの例:ifステートメントの条件がfalseの場合、xは定義されません。

3
Olivier Verdier

このコードをコマンドラインから実行しているため、if条件がtrueでxが設定されています。比較する:

>>> if False:
    y = 42


>>> y
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    y
NameError: name 'y' is not defined
2
SilentGhost