当我的程序运行引发异常的行时,有没有办法启动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的局部变量。 {i}仅在我在ipython中直接输入导致错误的命令时调用,即pdb
。
我不一定需要使用raise NameError("This, sent from the IPython prompt, will trigger pdb.")
,我只想访问pdb
中的变量。
编辑2:已经有一段时间了,IPython的func
选项现在正如我想要的那样工作。这意味着当我提出异常时,我可以回到-pdb
的范围内,并且可以毫无问题地阅读其变量func
和z
。即使没有设置g
选项,也可以在交互模式下运行IPython,然后在程序退出错误后调用魔术函数-pdb
- 这也将使您进入具有所有范围的交互式ipdb提示符accessibles。
答案 0 :(得分:22)
IPython v0.13的更新:
import sys
from IPython.core import ultratb
sys.excepthook = ultratb.FormattedTB(mode='Verbose',
color_scheme='Linux', call_pdb=1)
答案 1 :(得分:19)
这样做的:
ipython --pdb -c "%run exceptionTest.py"
在IPython初始化之后启动脚本,然后你进入正常的IPython + pdb环境。
答案 2 :(得分:12)
ipdb将IPython功能集成到pdb中。我使用以下代码将我的应用程序放入IPython调试器中,之后会出现无法处理的异常。
import sys, ipdb, traceback
def info(type, value, tb):
traceback.print_exception(type, value, tb)
ipdb.pm()
sys.excepthook = info
答案 3 :(得分:7)
@ snapshoe的回答不适用于较新版本的IPython。
但是这样做:
import sys
from IPython import embed
def excepthook(type, value, traceback):
embed()
sys.excepthook = excepthook
答案 4 :(得分:4)
您可以执行以下操作:
import sys
from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed()
def excepthook(type, value, traceback):
ipshell()
sys.excepthook = excepthook
答案 5 :(得分:4)
你可以试试这个:
from ipdb import launch_ipdb_on_exception
def main():
with launch_ipdb_on_exception():
# The rest of the code goes here.
[...]
答案 6 :(得分:3)
@ 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被导入。
答案 7 :(得分:2)
这个man page表示iPython有--[no]pdb
选项可以在命令行中传递,以启动未捕获异常的iPython。你在寻找更多吗?
编辑:
python -m pdb pythonscript.py
可以启动pdb。虽然不确定与iPython类似的事情。如果您正在寻找程序异常退出的堆栈跟踪和一般事后验证,这应该可行。
答案 8 :(得分:1)
你真的想在每个异常点打开一个pdb会话吗? (因为我认为从ipython打开的pdb会话与在普通shell中打开的会话相同)。如果是这样的话,这就是诀窍: http://code.activestate.com/recipes/65287-automatically-start-the-debugger-on-an-exception/
答案 9 :(得分:1)
如果你想同时获取回溯并在异常点打开一个带有环境的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])拉出名称空间信息