显示导致Python异常的源代码

s1ag04yj  于 7个月前  发布在  Python
关注(0)|答案(2)|浏览(42)

如何检索导致异常的代码行(而不是行号)?
这是一次尝试。

import sys, inspect
try:
    1 / 0
except Exception as e:
    exc_type, exc_obj, exc_tb = sys.exc_info()
    code = str(inspect.getsourcelines(exc_tb.tb_frame.f_code))        

print(code)

字符串
它返回脚本的第一行,而不是导致异常的行。

(['import sys, inspect\n'], 1)

r1zk6ea1

r1zk6ea11#

下面的代码工作,但它是不灵活的。别人可能有更好的解决方案。

import sys, inspect
try:
    y = 2
    a = 1 / 0
except Exception as e:
    exception_occr_at_file = inspect.trace()[0][1]
    line_no = inspect.trace()[0][2]
    code = inspect.trace()[0][4]

print(exception_occr_at_file)
print(line_no)
print(code)

#Ouput:
C:\Users\jianc\Desktop\test\test_print.py
4
['    a = 1 / 0\n']

字符串

sqxo8psd

sqxo8psd2#

为了补充spinx的答案,每个FrameInfo对象中都有属性
因此,我们可以通过使用它们来使代码更具可读性:

import sys, inspect

try:
    y = 2
    a = 1 / 0
except Exception as e:
    exception_occr_at_file = inspect.trace()[0].filename
    line_no = inspect.trace()[0].lineno
    code = inspect.trace()[0].code_context

print(exception_occr_at_file)
print(line_no)
print(code)

字符串
我也不太高兴在0的随机索引的框架。阅读的描述inspect.info,它听起来不像正确的位置被索引。
inspect.trace(context=1)返回当前帧和当前处理异常的帧之间的堆栈的FrameInfo对象列表。列表中的第一个条目表示调用者;最后一个条目表示异常的引发位置。
0将给予调用者的行,而不是抛出者的行。一个很好的例子是here。(为了方便使用,我在这里复制它。)

import sys
import inspect
from pprint import pprint

def errorer():
    raise Exception('foo')

def syser():
    try:
        errorer()
    except Exception, e:
        tb = sys.exc_info()[2]
        print tb.tb_frame
        print tb.tb_lasti
        print tb.tb_lineno
        print tb.tb_next

def inspecter():
    try:
        errorer()
    except Exception, e:
        pprint(inspect.trace())


输出如下:

>>> syser()
<frame object at 0x1441240>
6
10
<traceback object at 0x13eb3b0>
>>> inspecter()
[(<frame object at 0x14a5590>,
  '/tmp/errors.py',
  22,
  'inspecter',
  None,
  None),
 (<frame object at 0x14a21b0>,
  '/tmp/errors.py',
  8,
  'errorer',
  None,
  None)]


我们可以清楚地看到,在0处的索引为我们提供了在inspecter中调用函数errorer的行,而-1为我们提供了抛出异常的点。
因此,如果我们想知道哪一行抛出异常,-1是正确的,但是如果我们想知道失败函数/对象的调用树的根,0是正确的。

相关问题