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


266

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

if __name__ == '__main__':
    x = 1

print x

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


17
別の癖は、あなたは認識していない可能性があります場合はif上記の文は(すなわち、真の保持していない__name__はない '__main__'あなたの代わりにトップレベルにそれを実行するのでモジュールをインポートする場合など)、そしてx拘束されず、それ以降されているんprint x声明をスローしNameError: name 'x' is not definedます。
サンタ

回答:


302

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

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



105

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

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

use(x)

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

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

if False:
    x = 3
print(x)

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


42

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

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

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

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

  • ビルトインを検索

ソース

ことを通知if何かで宣言されて、唯一のクラス、関数、モジュールはPythonでスコープを提供する-と他のループ/構築物が記載されていない分岐ifブロックの外側declearedものと同じ範囲を有するブロック。変数はコンパイル時にチェックされないため、他の言語が例外をスローします。Pythonでは、必要なときに変数が存在する限り、例外はスローされません。


9

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

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

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

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


9

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

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


クラスはスコープを作成しません。クラス内の「ローカル」変数は、作成時にクラスの辞書に追加されるだけです。
chepner

3

はい。それはまた真実ですforスコープ。もちろん機能しません。

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


2

コマンドラインからこのコードを実行しているため、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

0

また、Pythonの型は実行時にのみチェックされるため、次のようなコードを使用できます。

if True:
    x = 2
    y = 4
else:
    x = "One"
    y = "Two"
print(x + y)

しかし、型の問題が原因でコードがエラーなしで動作する他の方法を考えるのに苦労しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.