假设我有一个引发意外异常的函数,所以我将它包装在ipdb中:
def boom(x,y):
try:
x / y
except Exception as e:
import ipdb; ipdb.set_trace()
def main():
x = 2
y = 0
boom(x,y)
if __name__ == '__main__':
main()
我可以向上移动堆栈以找出x和y具有的值:
$python crash.py
> /tmp/crash.py(6)boom()
5 except Exception as e:
----> 6 import ipdb; ipdb.set_trace()
7
ipdb> u
> /tmp/crash.py(11)main()
10 y = 0
---> 11 boom(x,y)
12
ipdb> p y
0
但是,在调试时,我想把调试器放在最顶层:
def boom(x,y):
x / y
def main():
x = 2
y = 0
boom(x,y)
if __name__ == '__main__':
try:
main()
except Exception as e:
import ipdb; ipdb.set_trace()
$python crash.py
> /tmp/crash.py(14)ipdb; ipdb.set_trace()
ipdb> !import traceback; traceback.print_exc(e)
Traceback (most recent call last):
File "crash.py",line 12,in ipdb> d # I want to see what value x and y had!
*** Newest frame
异常发生时,异常对象显然仍然具有对堆栈的引用.我可以在这里访问x和y,即使堆栈已经解开了吗?
最佳答案
事实证明,可以从traceback对象中提取变量.
要手动提取值:
ipdb> !import sys
ipdb> !tb = sys.exc_info()[2]
ipdb> p tb.tb_next.tb_frame.f_locals
{'y': 0,'x': 2}
更好的是,您可以使用异常在该堆栈上显式执行事后调试:
import sys
def boom(x,y)
if __name__ == '__main__':
try:
main()
except Exception as e:
# Most debuggers allow you to just do .post_mortem()
# but see https://github.com/gotcha/ipdb/pull/94
tb = sys.exc_info()[2]
import ipdb; ipdb.post_mortem(tb)
这让我们直接看到了令人讨厌的代码:
> /tmp/crash.py(4)boom()
3 def boom(x,y):
----> 4 x / y
5
ipdb> p x
2
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。