调用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())
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())