为什么python linecache会影响回溯模块,而不是常规的回溯?

Why does the Python linecache affect the traceback module but not regular tracebacks?

考虑下面的python程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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()

我动态地定义了一个引发异常并将其添加到linecache中的函数。代码的输出是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

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

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


默认的sys.excepthook使用一个单独的C级回溯打印实现,而不是traceback模块。(也许是这样的,即使系统太抽象而不能使用traceback.py,它仍然可以工作。)C实现并不尝试使用linecache。您可以在_Py_DisplaySourceLine中看到它用来检索源代码行的代码。

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

1
2
3
import sys
import traceback
sys.excepthook = traceback.print_exception