【问题标题】:Why does the Python linecache affect the traceback module but not regular tracebacks?为什么 Python linecache 会影响 traceback 模块,但不会影响常规 traceback?
【发布时间】:2018-11-04 01:17:08
【问题描述】:

考虑以下 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()

我正在动态定义一个引发异常并将其添加到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

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

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

【问题讨论】:

    标签: python traceback


    【解决方案1】:

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

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

    import sys
    import traceback
    sys.excepthook = traceback.print_exception
    

    【讨论】:

    • 如果我正确读取了 C 源代码,它只会打开文件并每次读取它(没有行缓存)。所以我猜你的解决方案是唯一合理的解决方法。
    猜你喜欢
    • 2020-07-23
    • 2011-03-06
    • 2016-12-09
    • 2018-12-16
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    相关资源
    最近更新 更多