【发布时间】:2013-09-23 13:16:26
【问题描述】:
如果 one 在最初抛出的函数之外捕获了异常,则会失去对本地堆栈的访问权限。因此,无法检查可能导致异常的变量的值。
有没有办法在抛出异常时自动开始中断调试器 (import pdb; pdb.set_trace()) 以检查本地堆栈?
【问题讨论】:
-
import pdb; pdb.set_trace()我们最喜欢的线路❤️
如果 one 在最初抛出的函数之外捕获了异常,则会失去对本地堆栈的访问权限。因此,无法检查可能导致异常的变量的值。
有没有办法在抛出异常时自动开始中断调试器 (import pdb; pdb.set_trace()) 以检查本地堆栈?
【问题讨论】:
import pdb; pdb.set_trace()我们最喜欢的线路❤️
您不想在每个异常上都中断;惯用的 Python 代码大量使用异常 (EAFP),因此您会不断插入不相关的代码。
改为使用 pdb 事后分析:import pdb; pdb.pm()。这使用sys.last_traceback 来检查堆栈,包括在抛出点的本地人。
【讨论】:
pdb.set_trace() 就像你在问题中所说的应该也可以,这是我通常使用的(不确定有什么区别)
sys.last_traceback 声明“这三个变量并不总是被定义;”在这种情况下,使用 pdb.post_mortem 有时会有所帮助。
ipython 支持这个 (http://ipython.org)。从 ipython 内部,做
%pdb on
从那时起,每当您遇到异常时,它都会自动将您放入调试器中。
请注意,在一般使用中,您(可能)很快就会厌倦...每次您输入错误并遇到语法错误时,您都必须退出调试器。但它有时很有用。
【讨论】:
我在What is the simplest way of using Python pdb to inspect the cause of an unhandled exception? 的回复中找到了我想要的东西
用那个包裹它:
def debug_on(*exceptions): if not exceptions: exceptions = (AssertionError, ) def decorator(f): @functools.wraps(f) def wrapper(*args, **kwargs): try: return f(*args, **kwargs) except exceptions: pdb.post_mortem(sys.exc_info()[2]) return wrapper return decorator例子:
@debug_on(TypeError) def buggy_function() .... raise TypeError
【讨论】:
import functools,是的,示例中缺少它
对于 python 3(今天是 3.8),可以使用
python3 -m pdb myscript.py
来自docs:
当作为脚本调用时,pdb 会自动进入 post-mortem 如果被调试的程序异常退出,则进行调试。后 事后调试(或程序正常退出后),pdb 将 重新启动程序。自动重启会保留 pdb 的状态(例如 作为断点),并且在大多数情况下比退出 程序退出时的调试器。
注意,在启动时,python会直接进入pdb模式,你需要输入c然后enter开始运行脚本
【讨论】:
pdb.post_mortem() 的形式开始。有没有办法开始pdb.set_trace()?还是ipdb.set_trace()?
我知道这是旧的并且已经接受了答案,但我发现这很有用(对于 IPython): 使用 --pdb 选项启动 IPython
ipython --pdb <whatever command>
【讨论】:
如果您只想包装函数的某些内部部分,或者需要装饰多个函数,则可以使用上下文管理器作为已接受答案的替代方案。我现在正在使用这个捕获所有异常的简单版本。我还建议使用pudb
from contextlib import contextmanager
@contextmanager
def postmortem_pudb():
try:
yield
except Exception as exc:
pudb.post_mortem()
这样使用
with postmortem_pudb():
function_that_might_throw_some()
...
another_function_that_might_throw_some()
...
yet_another_function_that_might_throw_some()
【讨论】: