python-在异常情况下启动IPython shell
当我的程序运行引发异常的行时,是否可以启动IPython Shell或提示?
我对引发异常的上下文,变量,范围(和子范围)最感兴趣。 类似于Visual Studio的调试,当引发异常但未被任何人捕获时,Visual Studio将停止并为我提供调用堆栈以及每个级别存在的变量。
您是否认为有办法使用IPython获得类似的东西?
编辑:启动IPython时的-pdb选项似乎并没有达到我想要的功能(或者也许我不知道如何正确使用它,这完全有可能)。 我运行以下脚本:
def func():
z = 2
g = 'b'
raise NameError("This error will not be caught, but IPython still"
"won't summon pdb, and I won't be able to consult"
"the z or g variables.")
x = 1
y = 'a'
func()
使用命令:
ipython -pdb exceptionTest.py
当出现错误时,它将停止执行,但是会给我一个IPython提示,在这里我可以访问脚本的全局变量,但不能访问函数func的局部变量。 仅当我在ipython中直接键入会导致错误的命令时(即func)才调用-pdb。
我不一定需要使用-pdb,我只想访问func中的变量。
编辑2:已经有一段时间了,IPython的-pdb选项现在可以按照我的意愿工作。 这意味着当我引发异常时,我可以返回func的范围,并毫无问题地读取其变量z和g。 即使没有设置-pdb选项,也可以在交互模式下运行IPython,然后在程序错误退出后调用魔术函数%debug-这也会使您进入具有所有作用域的交互式ipdb提示符。
10个解决方案
24 votes
IPython v0.13的更新:
import sys
from IPython.core import ultratb
sys.excepthook = ultratb.FormattedTB(mode='Verbose',
color_scheme='Linux', call_pdb=1)
Adam Greenhall answered 2020-06-16T16:45:55Z
19 votes
正在做:
ipython --pdb -c "%run exceptionTest.py"
在IPython初始化之后启动脚本,您将进入正常的IPython + pdb环境。
rcoup answered 2020-06-16T16:46:19Z
12 votes
ipdb将IPython功能集成到pdb中。 在发生异常处理后,我使用以下代码将应用程序扔到IPython调试器中。
import sys, ipdb, traceback
def info(type, value, tb):
traceback.print_exception(type, value, tb)
ipdb.pm()
sys.excepthook = info
jon answered 2020-06-16T16:46:40Z
7 votes
@snapshoe的答案不适用于较新版本的IPython。
但是这样做:
import sys
from IPython import embed
def excepthook(type, value, traceback):
embed()
sys.excepthook = excepthook
bcoughlan answered 2020-06-16T16:47:04Z
6 votes
您可以尝试以下方法:
from ipdb import launch_ipdb_on_exception
def main():
with launch_ipdb_on_exception():
# The rest of the code goes here.
[...]
Sardathrion answered 2020-06-16T16:47:24Z
4 votes
您可以执行以下操作:
import sys
from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed()
def excepthook(type, value, traceback):
ipshell()
sys.excepthook = excepthook
请参阅sys.excepthook和嵌入IPython。
snapshoe answered 2020-06-16T16:47:49Z
3 votes
@Adam的工作就像一个魅力,除了IPython加载缓慢(在我的计算机上为800ms)之外。 在这里,我有一个技巧可以使负载变懒。
class ExceptionHook:
instance = None
def __call__(self, *args, **kwargs):
if self.instance is None:
from IPython.core import ultratb
self.instance = ultratb.FormattedTB(mode='Verbose',
color_scheme='Linux', call_pdb=1)
return self.instance(*args, **kwargs)
sys.excepthook = ExceptionHook()
现在我们不需要一开始就等待。 仅当程序崩溃时,才会导入IPython。
Ray answered 2020-06-16T16:48:14Z
2 votes
该手册页说,iPython具有python -m pdb pythonscript.py选项,该选项将在命令行中传递,以启动iPython捕获未捕获的异常。 您是否在寻找更多?
编辑:python -m pdb pythonscript.py可以启动pdb。 虽然不确定与iPython类似。 如果您正在寻找程序异常退出的堆栈跟踪和常规验尸,这应该可以工作。
vpit3833 answered 2020-06-16T16:48:40Z
1 votes
您是否真的想在每个异常点打开一个pdb会话? (因为我认为从ipython打开的pdb会话与在普通shell中打开的会话相同)。 如果真是这样,这是窍门:[http://code.activestate.com/recipes/65287-automatically-start-the-debugger-on-an-exception/]
dirksen answered 2020-06-16T16:49:00Z
1 votes
如果您既要获取回溯信息,又要在异常发生时打开带有环境的IPython Shell:
def exceptHook(*args):
'''A routine to be called when an exception occurs. It prints the traceback
with fancy formatting and then calls an IPython shell with the environment
of the exception location.
'''
from IPython.core import ultratb
ultratb.FormattedTB(call_pdb=False,color_scheme='LightBG')(*args)
from IPython.terminal.embed import InteractiveShellEmbed
import inspect
frame = inspect.getinnerframes(args[2])[-1][0]
msg = 'Entering IPython console at {0.f_code.co_filename} at line {0.f_lineno}'.format(frame)
savehook = sys.excepthook # save the exception hook
InteractiveShellEmbed()(msg,local_ns=frame.f_locals,global_ns=frame.f_globals)
sys.excepthook = savehook # reset IPython's change to the exception hook
import sys
sys.excepthook = exceptHook
请注意,有必要从回溯引用的最后一帧(arg [2])中提取名称空间信息。
bht answered 2020-06-16T16:49:24Z