调用ipdb的快捷方式?

Shortcut for invoking ipdb?

ipdb 太棒了;哇。问题是,当脚本崩溃时,我仍然必须进入代码并添加四行,这些行不需要 ton 的输入,但也不是什么都不需要。例如,假设这是错误的行:

1 = 2

自然,我明白了:

SyntaxError: can't assign to literal

如果出于某种原因我想调试该行并查看该行之前发生了什么(或当时堆栈中的其他地方),我通常会按如下方式更改该行代码:

try:
    1 = 2
except:
    import traceback;traceback.print_exc()
    import ipdb;ipdb.set_trace()

这就完成了工作,但我希望能够在 "mode" 中 运行 一个脚本,每当任何事情发生时(假设异常未被处理),我得到同样的结果。

存在吗?

*******编辑*******

感谢@np8 的回复,我重新编写了驱动程序脚本,使其看起来像这样(其中 main 是任意函数):

if __name__ == "__main__":
    start = time.time()
    args = parser.parse_args()

    if args.verbosity > 1:
        from ipdb import launch_ipdb_on_exception
        with launch_ipdb_on_exception():
            print("Launching ipdb on exception!")
            main(start, args)

    else:
        print("NOT launching ipdb on exception!")
        main(start, args)

这允许我从命令行确定异常是否应该启动 ipdb(即当我正在开发时)或不(即当脚本在生产中 运行ning 并且因此冗长在此示例中,参数低于 2)。

您要找的是"post mortem debugging"。获得所需内容的最简单方法是 运行 使用

的脚本
ipdb script.py

python -m pdb script.py

而不是

python script.py

您可以使用 launch_ipdb_on_exception 上下文管理器:

# test.py
from ipdb import launch_ipdb_on_exception

with launch_ipdb_on_exception():
    print(x)

运行 以上将导致启动 ipdb:

python .\test.py
NameError("name 'x' is not defined",)
> c:\tmp\delete_me\test.py(4)<module>()
      2
      3 with launch_ipdb_on_exception():
----> 4     print(x)

ipdb>

pm 是一个函数装饰器,它反映了 ipdb 上下文管理器 launch_ipdb_on_exception。用它来装饰 一个函数,该函数将在出错时转到 ipdb。 'pm' 这个名字来自 ipdb.pm() 函数,它代表 尸检,并且表现相似。

这样,你就可以用@pm修饰你要调试的顶层函数,调用栈中该层或更低层的任何异常都会触发ipdb。

import ipdb


class Decontext(object):
    """
    Makes a context manager also act as decorator
    """
    def __init__(self, context_manager):
        self._cm = context_manager

    def __enter__(self):
        return self._cm.__enter__()

    def __exit__(self, *args, **kwds):
        return self._cm.__exit__(*args, **kwds)

    def __call__(self, func):
        def wrapper(*args, **kwds):
            with self:
                return func(*args, **kwds)
        return wrapper

pm = Decontext(ipdb.launch_ipdb_on_exception())