美文网首页
Python代码调试

Python代码调试

作者: 叩丁狼教育 | 来源:发表于2018-11-01 14:07 被阅读26次

本文作者:黎智煊,叩丁狼高级讲师。原创文章,转载请注明出处。

调试

程序能一次写完并正常运行的概率很小,基本不超过1%。总会有各种各样的bug需要修正。有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误的,因此,需要一整套调试程序的手段来修复bug。

  1. 第一种方法简单直接粗暴有效,就是用print()把可能有问题的变量打印出来看看:
def foo(s):
    n = int(s)
    print('>>> n = %d' % n)
    return 10 / n

def main():
    foo('0')

main()

执行后在输出中查找打印的变量值:

$ python err.py
>>> n = 0
Traceback (most recent call last):
  ...
ZeroDivisionError: integer division or modulo by zero

用print()最大的坏处是将来还得删掉它,想想程序里到处都是print(),运行结果也会包含很多垃圾信息。所以,我们又有第二种方法。

断言

凡是用print()来辅助查看的地方,都可以用断言(assert)来替代:

def foo(s):
    n = int(s)
    assert n != 0, 'n is zero!'
    return 10 / n

def main():
    foo('0')

assert的意思是,表达式n != 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错。

如果断言失败,assert语句本身就会抛出AssertionError:

$ python err.py
Traceback (most recent call last):
  ...
AssertionError: n is zero!

程序中如果到处充斥着assert,和print()相比也好不到哪去。不过,启动Python解释器时可以用-O参数来关闭assert:

$ python -O err.py
Traceback (most recent call last):
  ...
ZeroDivisionError: division by zero

关闭后,你可以把所有的assert语句当成pass来看。

logging

把print()替换为logging是第3种方式,和assert比,logging不会抛出错误,而且可以输出到文件:

import logging

s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)

logging.info()就可以输出一段文本。运行,发现除了ZeroDivisionError,没有任何信息。怎么回事?

在import logging之后添加一行配置再试试:

import logging
logging.basicConfig(level=logging.INFO)

看到输出了:

$ python err.py
INFO:root:n = 0
Traceback (most recent call last):
  File "err.py", line 8, in <module>
    print(10 / n)
ZeroDivisionError: division by zero

  • 这就是logging的好处,它允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。同理,指定level=WARNING后,debuginfo就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。

  • logging的另一个好处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。

pdb

Debug 对于任何开发人员都是一项非常重要的技能,它能够帮助我们准确的定位错误,发现程序中的 bug。python 提供了一系列 debug 的工具和包,可供我们选择。本文将主要阐述如何利用 python debug 相关工具进行 debug。

第4种方式是启动Python的调试器pdb
使用 pdb 进行调试

pdb 是 python 自带的一个包,为 python 程序提供了一种交互的源代码调试功能,主要特性包括设置断点、单步调试、进入函数调试、查看当前代码、查看栈片段、动态改变变量的值等。pdb 提供了一些常用的调试命令,详情见表 1。

pdb 常用命令

命令 解释
break 或 b 设置断点 设置断点
continue 或 c 继续执行程序
list 或 l 查看当前行的代码段
step 或 s 进入函数
return 或 r 执行代码直到从当前函数返回
exit 或 q 中止并退出
next 或 n 执行下一行
pp 打印变量的值
help 帮助

让程序以单步方式运行,可以随时查看运行状态。我们先准备好程序:

# err.py
s = '0'
n = int(s)
print(10 / n)

然后启动:

$ python -m pdb err.py
> /Users/michael/Github/learn-python3/samples/debug/err.py(2)<module>()
-> s = '0'

以参数-m pdb启动后,pdb定位到下一步要执行的代码-> s = '0'。输入命令l来查看代码:

(Pdb) l
  1     # err.py
  2  -> s = '0'
  3     n = int(s)
  4     print(10 / n)

输入命令n可以单步执行代码:

(Pdb) n
> /Users/michael/Github/learn-python3/samples/debug/err.py(3)<module>()
-> n = int(s)
(Pdb) n
> /Users/michael/Github/learn-python3/samples/debug/err.py(4)<module>()
-> print(10 / n)

任何时候都可以输入命令p 变量名来查看变量:

(Pdb) p s
'0'
(Pdb) p n
0

输入命令q结束调试,退出程序:

(Pdb) q

这种通过pdb在命令行调试的方法理论上是万能的,但实在是太麻烦了,如果有一千行代码,要运行到第999行得敲多少命令啊。还好,我们还有另一种调试方法。

pdb.set_trace()

这个方法也是用pdb,但是不需要单步执行,我们只需要import pdb,然后,在可能出错的地方放一个pdb.set_trace(),就可以设置一个断点:

# err.py
import pdb

s = '0'
n = int(s)
pdb.set_trace() # 运行到这里会自动暂停
print(10 / n)

运行代码,程序会自动在pdb.set_trace()暂停并进入pdb调试环境,可以用命令p查看变量,或者用命令c继续运行:

$ python err.py 
> /Users/michael/Github/learn-python3/samples/debug/err.py(7)<module>()
-> print(10 / n)
(Pdb) p n
0
(Pdb) c
Traceback (most recent call last):
  File "err.py", line 7, in <module>
    print(10 / n)
ZeroDivisionError: division by zero

这个方式比直接启动pdb单步调试效率要高很多,但也高不到哪去。

其他调试方式

可以使用各类IDE自带的调试工具,优秀的python工具有pycharm,visual studio code,pydev等等.

想获取更多技术视频,请前往叩丁狼官网:http://www.wolfcode.cn/openClassWeb_listDetail.html

相关文章

  • 参考资料:Python 的调试

    Python 代码调试技巧 我常用的 Python 调试工具 详细演示进入函数的 pdb s 调试 Python ...

  • Ansible 开发调试 之【pdb本地调试】

    Ansible是用Python编写的,用于调试本地代码执行的工具是Python调试器 **pdb**。这个工具允许...

  • Python代码调试

    本文作者:黎智煊,叩丁狼高级讲师。原创文章,转载请注明出处。 调试 程序能一次写完并正常运行的概率很小,基本不超过...

  • Python 必需学会的调式方法

    没错就是pdb 调试,pdb 是 python 的一个内置模块,用于命令行来调试 Python 代码。或许你会说,...

  • tensorflow-gpu使用

    python代码中设置使用的GPU 如果要在python代码中设置使用的GPU(如使用pycharm进行调试时),...

  • 来不及解释快上车的 PDB 调试指南

    什么是 PDB PDB 全称 Python Debugger,专门调试 Python 程序的官方库。 有代码就有 ...

  • python 调试

    使用 pdb 进行调试 pdb 是 python 自带的一个包,为 python 程序提供了一种交互的源代码调试功...

  • Python 调试冷知识

    对于 python 代码的调试我们通常都是使用 IDE 自带的调试功能。但是 IDE 提供的调试功能存在局限性,例...

  • pdb python代码调试

    在for 循环前和for 循环后加入pdb.set_trace()

  • vscode - Python - Error: spawn p

    使用VScode测试Python·代码时无法调试,对于Python来说,环境问题,学习成本高,使用次数少,学习起来...

网友评论

      本文标题:Python代码调试

      本文链接:https://www.haomeiwen.com/subject/bycxxqtx.html