Python解释器报告异常时出现意外行

2024-04-23 20:25:57 发布

您现在位置:Python中文网/ 问答频道 /正文

当Python解释器报告一个错误/异常(从现在开始,我只想说“error”来指代这两个错误)时,它会打印导致错误的行号和内容。你知道吗

有趣的是,如果有一个长时间运行的Python脚本导致错误,并且在脚本运行时更改了.py文件,那么解释器可以根据.py文件的更改内容报告错误行。你知道吗

中全景:

样本.py

from time import sleep

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

raise Exception("foo", "bar")

此脚本运行10秒,然后引发异常。你知道吗

样本2.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. 在第二个终端窗口中,mv sample.py sample.py.bak && cp sample2.py sample.pysample.py完成执行之前

预期行为

口译员报告如下:

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

在这里,解释器报告在sample.py的第7行有一个异常,并打印该异常。你知道吗

实际行为

口译员报告如下:

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. 我对翻译工作的理解是否还有其他缺陷?你知道吗

Tags: 文件sample内存inpy脚本内容foo
1条回答
网友
1楼 · 发布于 2024-04-23 20:25:57

根据@b\u c链接的the answer

Python doesn't keep track of what source code corresponds to any compiled bytecode. It might not even read that source code until it needs to print a traceback.

[...]

When Python needs to print a traceback, that's when it tries to find source code corresponding to all the stack frames involved. The file name and line number you see in the stack trace are all Python has to go on

[...]

The default sys.excepthook goes through the native call PyErr_Display, which eventually winds up using _Py_DisplaySourceLine to display individual source lines. _Py_DisplaySourceLine unconditionally tries to find the file in the current working directory (for some reason - misguided optimization?), then calls _Py_FindSourceFile to search sys.path for a file matching that name if the working directory didn't have it.

相关问题 更多 >