Python ルーチンを書きましたが、間違いがありました:false
の代わりにFalse
. ただし、コンパイル時に発見されませんでした。不正行為を通知するために、プログラムはこの行まで実行する必要がありました。
なぜそうなのですか?Pythonインタープリター/コンパイラーの何がそれを機能させるのですか?
何か参考になりましたか?
Python ルーチンを書きましたが、間違いがありました:false
の代わりにFalse
. ただし、コンパイル時に発見されませんでした。不正行為を通知するために、プログラムはこの行まで実行する必要がありました。
なぜそうなのですか?Pythonインタープリター/コンパイラーの何がそれを機能させるのですか?
何か参考になりましたか?
Python の動的な性質により、コンパイル時に未定義の名前を検出することは不可能です。構文のみがチェックされます。構文に問題がなければ、コンパイラがバイトコードを生成し、Python がコードの実行を開始します。
この例では、グローバル名への参照を取得しますfalse
。バイトコード インタープリターが実際にこのグローバル名にアクセスしようとした場合にのみ、エラーが発生します。
説明のために、ここに例を示します。次のコードは問題なく実行できると思いますか?
globals()["snyfr".decode("rot13")] = 17
x = false
最初の行は という名前の変数を動的に生成するため、実際にはそうfalse
です。
これは、名前を検索するタイミングについてインタプリタが「怠惰」であると考えることができます。プログラムの他のビットが既知の変数の辞書をいじくり回す可能性があるため、可能な限り遅くなります。
プログラムを検討する
>>> def foo():
... return false
...
>>> def bar():
... global false
... false = False
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in foo
NameError: global name 'false' is not defined
>>> bar()
>>> foo()
False
Pythonを実行した時点では何が何であるかを知らなかったため、最初の呼び出しで。がfoo
発生したことに注意してください。ただし、グローバルスコープを変更し、の別の名前として挿入しました。NameError
foo
false
bar
false
False
この種の名前空間のマッキングにより、プログラムの作成方法に大きな柔軟性がもたらされます。もちろん、より制限の厳しい言語でチェックできる多くのことも削除されます。