3

Python インタープリターがエラー/例外を報告すると (これからは、これらの両方を指すために「エラー」とだけ言います)、行番号とエラーの原因となった行の内容を出力します。

興味深いことに、エラーを引き起こし、スクリプトの実行中にファイルを変更する実行時間の長い Python スクリプトがある.py場合、インタープリターは、変更されたファイルの内容に基づいて、エラーを発生させたとして誤った行を報告でき.pyます。

MWE:

サンプル.py

from time import sleep

for i in range(10):
    print(i)
    sleep(1)

raise Exception("foo", "bar")

このスクリプトは 10 秒間実行され、その後例外が発生します。

sample2.py

from time import sleep

for i in range(10):
    print(i)
    sleep(1)
"""
This
is
just
some
filler
to
demonstrate
the
behavior
"""
raise Exception("foo", "bar")

このファイルはsample.py、ループの終わりと行の間にジャンクがあり、次の例外が発生することを除いて、 と同じです。

Traceback (most recent call last):
  File "sample.py", line 7, in <module>
Exception: ('foo', 'bar')

私がしたこと

  1. python3 sample.py
  2. 2 番目のターミナル ウィンドウで、実行が終了mv sample.py sample.py.bak && cp sample2.py sample.pyする前にsample.py

予想される行動

インタープリターは次のように報告します。

Traceback (most recent call last):
  File "sample.py", line 7, in <module>
Exception: ('foo', 'bar')

ここで、インタープリターは の 7 行目に例外があったことを報告し、例外sample.pyを出力します。

実際の動作

インタープリターは次のように報告します。

Traceback (most recent call last):
  File "sample.py", line 7, in <module>
    """
Exception: ('foo', 'bar')

ここで、インタープリター"""は例外を報告するときにも報告します。この情報を見つけるために、プログラムを実行するためにメモリにロードされたファイルではなく、ディスク上のファイルを調べているようです。

私の混乱の原因

以下は、実行時に何が起こるかについての私のメンタル モデルですpython3 sample.py

  1. インタプリタは の内容sample.pyをメモリにロードします
  2. インタプリタは字句解析、意味解析、コード生成などを実行してマシンコードを生成します
  3. 生成されたコードはCPUに送られ実行されます
  4. エラーが発生した場合、インタープリターはソース コードのメモリ内表現を参照してエラー メッセージを生成します。

明らかに、私のメンタル モデルには欠陥があります。

私が知りたいこと:

  1. Python インタープリターがメモリ内ではなく、ディスク上のファイルを参照してエラー メッセージを生成するのはなぜですか?
  2. 通訳者が何をしているのかについての私の理解に、他に何か欠陥がありますか?
4

1 に答える 1

1

@b_cによってリンクされた回答によると、

Python は、コンパイルされたバイトコードに対応するソース コードを追跡しません。トレースバックを出力する必要があるまで、そのソース コードを読み取らない場合もあります。

[...]

Python がトレースバックを出力する必要があるときは、関連するすべてのスタック フレームに対応するソース コードを見つけようとするときです。スタック トレースに表示されるファイル名と行番号は、Python で実行する必要があるすべてです。

[...]

デフォルトsys.excepthookはネイティブ コールを通過し、最終PyErr_Display的に_Py_DisplaySourceLine個々のソース行を表示するために使用されます。_Py_DisplaySourceLine無条件に現在の作業ディレクトリでファイルを見つけようとします (何らかの理由で - 誤った最適化?)。次に、作業ディレクトリにない場合は、その名前に一致するファイル_Py_FindSourceFileを検索するように呼び出します。sys.path

于 2019-10-10T14:48:24.093 に答える