IPython功能(5)Errors和Debugging

控制Error显示:%xmode

一般error显示在trackback里,你可以使用magic函数%xmode来控制error的输出,比如现在有下面这个一个Error显示:

def func1(a, b):
    return a / b

def func2(x):
    a = x
    b = x - 1
    return func1(a, b)
func2(1)
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-2-b2e110f6fc8f> in <module>()
----> 1 func2(1)

<ipython-input-1-d849e34d61fb> in func2(x)
      5     a = x
      6     b = x - 1
----> 7     return func1(a, b)

<ipython-input-1-d849e34d61fb> in func1(a, b)
      1 def func1(a, b):
----> 2     return a / b
      3 
      4 def func2(x):
      5     a = x

ZeroDivisionError: division by zero

%xmode有三个选项:Plain, Context, 和Verbose;默认是Context,也就是跟刚刚一样的输出,Plain可以给到更简洁的输出:

%xmode Plain
Exception reporting mode: Plain
func2(1)
Traceback (most recent call last):

  File "<ipython-input-4-b2e110f6fc8f>", line 1, in <module>
    func2(1)

  File "<ipython-input-1-d849e34d61fb>", line 7, in func2
    return func1(a, b)

  File "<ipython-input-1-d849e34d61fb>", line 2, in func1
    return a / b

ZeroDivisionError: division by zero

Plain可以给到更详细的输出,包括function的argument:

%xmode Verbose
Exception reporting mode: Verbose
func2(1)
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-6-b2e110f6fc8f> in <module>()
----> 1 func2(1)
        global func2 = <function func2 at 0x103729320>

<ipython-input-1-d849e34d61fb> in func2(x=1)
      5     a = x
      6     b = x - 1
----> 7     return func1(a, b)
        global func1 = <function func1 at 0x1037294d0>
        a = 1
        b = 0

<ipython-input-1-d849e34d61fb> in func1(a=1, b=0)
      1 def func1(a, b):
----> 2     return a / b
        a = 1
        b = 0
      3 
      4 def func2(x):
      5     a = x

ZeroDivisionError: division by zero

Debugging:光看trackback是不够的

Python内置的debugger是pdb,它允许你一句句地检查code,IPython相应的函数是ipdb。
在IPython里最方便的debugger可能是magic函数%debug。输入此函数后会自动打开一个debugging的交互界面,其中的ipdb提示可以探索堆栈的当前状态、探索可用变量,甚至运行 Python 命令。

我们先来检查一下最近的一个出错,做一些简单的print,并输入exit退出debugging界面:

%debug
> <ipython-input-1-d849e34d61fb>(2)func1()
      1 def func1(a, b):
----> 2     return a / b
      3 

ipdb> print(a)
1
ipdb> print(b)
0
ipdb> quit

我们还可以在堆栈里上下求索,探索变量值:

%debug
> <ipython-input-1-d849e34d61fb>(2)func1()
      1 def func1(a, b):
----> 2     return a / b
      3 

ipdb> up
> <ipython-input-1-d849e34d61fb>(7)func2()
      5     a = x
      6     b = x - 1
----> 7     return func1(a, b)

ipdb> print(x)
1
ipdb> up
> <ipython-input-6-b2e110f6fc8f>(1)<module>()
----> 1 func2(1)

ipdb> down
> <ipython-input-1-d849e34d61fb>(7)func2()
      5     a = x
      6     b = x - 1
----> 7     return func1(a, b)

ipdb> quit

这不仅可以快速找出导致错误的原因,还可以快速找出导致错误的函数调用。

如果你想每次出错的时候自动开启这个debugging界面,你可以用%pdb来打开这个自发程序:

%xmode Plain
%pdb on
func2(1)
Exception reporting mode: Plain
Automatic pdb calling has been turned ON
Traceback (most recent call last):

  File "<ipython-input-9-569a67d2d312>", line 3, in <module>
    func2(1)

  File "<ipython-input-1-d849e34d61fb>", line 7, in func2
    return func1(a, b)

  File "<ipython-input-1-d849e34d61fb>", line 2, in func1
    return a / b

ZeroDivisionError: division by zero
> <ipython-input-1-d849e34d61fb>(2)func1()
      1 def func1(a, b):
----> 2     return a / b
      3 

ipdb> print(b)
0
ipdb> quit

如果你有一个脚本,你想在交互模式下从头开始运行,你可以输入命令%run -d,并用next命令继续浏览命令行。

部分调试命令列表

命令 功能
list 显示文件的当前位置
h(elp) 显示命令列表,或查找特定命令的帮助
q(uit) 退出debugger或退出程序
c(ontinue) 退出debugger,继续程序
n(ext) 到程序下一行
<enter> 重复上一条命令
p(rint) 打印变量
s(tep) 进入子程序
r(eturn) 退出子程序
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。