为什么 Python linecache 会影响回溯模块而不影响常规回溯?

asm*_*rer 6 python traceback

考虑以下 Python 程序:

code = """
def test():
    1/0
"""

filename = "<test>"

c = compile(code, filename, 'exec')
exec(c)

import linecache

linecache.cache[filename] = (len(code), None, code.splitlines(keepends=True), filename)

import traceback

print("Traceback from the traceback module:")
print()
try:
    test()
except:
    traceback.print_exc()

print()
print("Regular traceback:")
print()

test()
Run Code Online (Sandbox Code Playgroud)

我正在动态定义一个引发异常的函数并将其添加到linecache. 代码的输出是

Traceback from the traceback module:

Traceback (most recent call last):
  File "test.py", line 20, in <module>
    test()
  File "<test>", line 3, in test
    1/0
ZeroDivisionError: division by zero

Regular traceback:

Traceback (most recent call last):
  File "test.py", line 28, in <module>
    test()
  File "<test>", line 3, in test
ZeroDivisionError: division by zero
Run Code Online (Sandbox Code Playgroud)

如果我然后使用traceback模块从该函数获得回溯,则会显示该函数的代码行(1/0第一个回溯的部分)。但是,如果我只是让代码引发异常并从解释器获取常规回溯,则不会显示代码。

为什么常规解释器回溯不使用行缓存?有没有办法让代码出现在常规回溯中?

use*_*ica 7

默认sys.excepthook使用单独的 C 级回溯打印实现,而不是traceback模块。(也许是这样,即使系统太无聊而无法使用它,它仍然可以工作traceback.py。)C 实现不会尝试使用linecache. 您可以在_Py_DisplaySourceLine.

如果您希望回溯使用traceback模块的实现,您可以替换sys.excepthooktraceback.print_exception

import sys
import traceback
sys.excepthook = traceback.print_exception
Run Code Online (Sandbox Code Playgroud)