2012-02-21 2 views
0

ここPythonでは関数定義のエラーが検出されませんか?

#a.py 

def bar(): 
    print x #x not defined, apparently will result in an error 

def foo(): 
    pass 

if __name__ == '__main__': 
    foo() 

上記モジュールがエラーなし($ python a.py)を実行することができ、Pythonモジュールです。どうして?ちょうどbar__main__で使用されていないからですか?

しかし、barの定義は実行されますか?

答えて

4

はい、barの定義は実行されますが、定義にはエラーはありません。関数が呼び出されたときに存在する限り、まだ存在しないグローバルを参照する関数を定義することは有効なPythonです。これを考慮してください:

def bar(): 
    print x 

x = 10 
if __name__ == '__main__': 
    bar() 

これはエラーにはなりません。関数が定義された時点でxが存在していても、後でdelを使用してそれを停止するものは何もないので、これは賢明なことです。 xを定義する必要があるのは、barが定義されていないときは、barが呼び出されたときです(これまでの場合)。

もしあなたが示唆しているようにPythonがうまくいけば、一時的に一つの名前をNoneにバインドして両方の関数を定義するというような、奇妙なハックを起こさずに相互再帰関数を定義することは不可能です。

EDIT:はコメント欄でオルコットの質問に対するイグナシオの答えについては詳しく説明し、関数が実行される前に、はい、構文エラーがキャッチされているが、それはどちらかに定義することができます前に、彼らは実際にキャッチしています。

ファイルを読み込むとき、Pythonはファイル全体を構文解析し、一度に1つずつ実行します。構文エラーとは、ファイルに含まれているステートメントを確認できなかったため、何かを実行できないことを意味します。したがって、ファイルがロードされたときにエラーが発生します。つまり、インタプリタで直接実行したとき、またはimportのときにエラーが発生します。

この前処理ステップは、Pythonが通常コンパイルされた言語として考えられていなくても、「コンパイル時間」として知られています。これは技術的にはバイトコード形式にコンパイルされていますが、バイトコードはソースコードステートメントを直接表現するだけなので、ほとんど興味深いものです。

+0

答えをクリアしてください。 :-) 'bar'の定義に構文エラーが含まれていると、定義が実行されたときに構文エラーが検出されます。 – Alcott

+1

構文エラーは実行時ではなくコンパイル時に捕捉されます。 –

+0

@Alcott:構文エラーの質問についてもう少し詳しく説明するセクションを追加しました。 – Ben

1

Pythonは実行時に名前のルックアップを解決します。

def bar(): 
    print x 

x = 3 
bar() 
+0

'bar'の定義の前に、グローバル変数' x'を定義する必要はありません、rignt? – Alcott

+0

これはまったく定義する必要はありません。 –

1

それはあなたがスクリプトを実行するときbar定義が実行されたことは事実です。しかし、スクリプト全体が実行されるまで、xという名前のグローバル変数が実際に存在するかどうかを判断することはできません。

たとえば、あなたが行うことができます:

if __name__ == '__main__': 
    if random.random() < 0.5: 
     x = 5 
    foo() 

コンパイラはxが存在する予定されているかどうか時間をコンパイルで決定することができません。

+0

したがって、 'bar()'を呼び出す直前に 'x'という名前のグローバル変数が定義されている限り、エラーはスローされません。 – Alcott

+0

そうです。しかし、これは*ランタイム*の決定であることに注意する必要があります。 –

関連する問題