[英]locals() and globals() in stack trace on exception (Python)
虽然堆栈跟踪在 Python 中很有用,但问题根源的数据通常会丢失——有没有办法确保至少将 locals()(可能还有 globals())添加到打印的堆栈跟踪中?
您可以安装自己的异常钩子并从那里输出您需要的内容:
import sys, traceback
def excepthook(type, value, tb):
traceback.print_exception(type, value, tb)
while tb.tb_next:
tb = tb.tb_next
print >>sys.stderr, 'Locals:', tb.tb_frame.f_locals
print >>sys.stderr, 'Globals:', tb.tb_frame.f_globals
sys.excepthook = excepthook
def x():
y()
def y():
foo = 1
bar = 0
foo/bar
x()
要在回溯中打印每个帧的变量,请将上述循环更改为
while tb:
print >>sys.stderr, 'Locals:', tb.tb_frame.f_locals
print >>sys.stderr, 'Globals:', tb.tb_frame.f_globals
tb = tb.tb_next
这是一盒潘多拉。 打印形式的值可能非常大; 在堆栈跟踪中打印所有局部变量很容易由于错误输出而导致新问题。 这就是为什么这在 Python 中一般没有实现。
但是,在小示例中,即如果您知道您的值不会太大而无法正确打印,您可以自己跟踪回溯:
import sys
import traceback
def c():
clocal = 1001
raise Exception("foo")
def b():
blocal = 23
c()
def a():
alocal = 42
b()
try:
a()
except Exception:
frame = sys.exc_info()[2]
formattedTb = traceback.format_tb(frame)
frame = frame.tb_next
while frame:
print formattedTb.pop(0), '\t', frame.tb_frame.f_locals
frame = frame.tb_next
输出将是这样的:
File "/home/alfe/tmp/stacktracelocals.py", line 19, in <module>
a()
{'alocal': 42}
File "/home/alfe/tmp/stacktracelocals.py", line 16, in a
b()
{'blocal': 23}
File "/home/alfe/tmp/stacktracelocals.py", line 12, in b
c()
{'clocal': 1001}
当然,您可以按照他的回答中建议的 thg435 安装您自己的 except 钩子。
如果您还不知道这一点,请使用 pdb post-mortem 功能:
x = 3.0
y = 0.0
print x/y
def div(a, b):
return a / b
print div(x,y)
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-3-d03977de5fc3> in div(a, b)
1 def div(a, b):
----> 2 return a / b
ZeroDivisionError: float division
import pdb
pdb.pm()
> <ipython-input-3-148da0dcdc9e>(2)div()
0 return a/b
ipdb> l
1 def div(a,b):
----> 2 return a/b
ipdb> a
3.0
ipdb> b
0.0
等。
当然,在某些情况下,您确实需要打印件。 您最好检测代码(通过 try/except)以打印出围绕您正在调试的特定奇怪异常的额外信息,而不是将其用于所有内容,恕我直言。
尝试带有变量的回溯包。
用法:
from traceback_with_variables import traceback_with_variables
def main():
...
with traceback_with_variables():
...your code...
例外情况:
Traceback with variables (most recent call last):
File "./temp.py", line 7, in main
return get_avg_ratio([h1, w1], [h2, w2])
sizes_str = '300 200 300 0'
h1 = 300
w1 = 200
h2 = 300
w2 = 0
File "./temp.py", line 10, in get_avg_ratio
return mean([get_ratio(h, w) for h, w in [size1, size2]])
size1 = [300, 200]
size2 = [300, 0]
File "./temp.py", line 10, in <listcomp>
return mean([get_ratio(h, w) for h, w in [size1, size2]])
.0 = <tuple_iterator object at 0x7ff61e35b820>
h = 300
w = 0
File "./temp.py", line 13, in get_ratio
return height / width
height = 300
width = 0
builtins.ZeroDivisionError: division by zero
安装:
pip install traceback-with-variables
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.