【问题标题】:Unexpected line given when Python interpreter reports exception [duplicate]Python解释器报告异常时给出的意外行[重复]
【发布时间】:2019-10-09 19:59:07
【问题描述】:

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

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

MWE:

sample.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. 在第二个终端窗口中,mv sample.py sample.py.bak &amp;&amp; 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. 如果出现错误,解释器会参考源代码的 in-memory 表示以生成错误消息

显然,我的心智模型存在缺陷。

我想知道的:

  1. 为什么 Python 解释器会查询磁盘上的文件来生成错误消息,而不是查看内存?
  2. 我对口译员所做工作的理解是否存在其他缺陷?

【问题讨论】:

  • 答案可能是here
  • @b_c 感谢链​​接,我在寻找解释时没有看到

标签: python exception interpreter pythoninterpreter


【解决方案1】:

根据@b_c 链接的the answer

Python 不会跟踪任何已编译字节码对应的源代码。在需要打印回溯之前,它甚至可能不会读取该源代码。

[...]

当 Python 需要打印回溯时,它会尝试查找与所涉及的所有堆栈帧对应的源代码。您在堆栈跟踪中看到的文件名和行号是 Python 必须继续进行的全部内容

[...]

default sys.excepthook 通过本机调用PyErr_Display,最终使用_Py_DisplaySourceLine 来显示各个源代码行。 _Py_DisplaySourceLine 无条件地尝试在当前工作目录中查找文件(出于某种原因 - 优化错误?),然后调用 _Py_FindSourceFile 搜索 sys.path 以查找与该名称匹配的文件(如果工作目录没有)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2011-01-12
    • 2018-04-03
    相关资源
    最近更新 更多