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

调试

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

  1. 第一种方法简单直接粗暴有效,就是用print()把可能有问题的变量打印出来看看:
def foo(s):n = int(s)print('>>> n = %d' % n)return 10 / ndef 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 / ndef 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 loggings = '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) l1     # err.py2  -> 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 pdbs = '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等等.

Python代码调试相关推荐

  1. 转:Python 代码调试技巧

    Python 代码调试技巧 转载于:https://www.cnblogs.com/kira2will/p/4254754.html

  2. 【QA】Python代码调试之解决Segmentation fault (core dumped)问题

    Python代码调试之解决Segmentation fault 问题 问题描述 排查过程 1. 定位错误, 2. 解决办法 参考资料 问题描述 Python3执行某一个程序时,报Segmentatio ...

  3. python代码调试中间变量_Python代码调试的那些“最少且必要”技巧

    原标题:Python代码调试的那些"最少且必要"技巧 异常处理模块能帮助我们在运行期间处理异常信息,但Python代码还有更为基础的错误--语法错误和逻辑错误. 语法错误相对简单, ...

  4. Python代码调试方法

    对于每个程序开发者来说,调试几乎是必备技能.常用Pycharm编辑器里的方法有Print大法.log大法,但缺少类似Matlab的变量区,给代码调试带来不便,特别是在有函数的情况下,变量无法实时查看. ...

  5. python代码调试快捷键_6. Pycharm的传参、快捷键、执行代码、调试模式

    1.通过pycharm给python程序传递参数 脚本传入的参数.多个参数这个大家都比较熟悉,就不多说了 Pycharm如何传入参数? 先来认识python的参数: sys.argv[0]脚本本身 s ...

  6. Eclipse中调试Python代码--调试FWTools2.4.7中的gdal_retile.py

    Eclipse中调试Python代码 Gdal_retile.py是用于对遥感影像创建金字塔,近期本人想读懂改程序中的代码.读懂代码的较好方式就是单步调试,但是由于之前没有学过Python语言,不但对 ...

  7. Python 代码调试二三事

    ♚ 作者王维栋,网易游戏运维与基础架构部,产品软件设计师,专注于智能监控.性能优化等领域. 本文来自<网易游戏运维平台 (neteasegameops)>微信公众号的投稿,隶属于网易游戏运 ...

  8. eclipse 下安装PyDev并导入faster rcnn python代码调试

    Python在算法研究应用非常广泛,最近要研究faster rcnn的python代码,就得学习python,所以就需要一个趁手的工具来看python代码,否则只是用文本编译器找代码实在是太影响效率了 ...

  9. 简单实用,Python代码调试利器

    ❝ 本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes ❞ 1 简介 尽管有那么多花里胡哨的debug工 ...

  10. 【转】Python 代码调试技巧

    原文网址:http://www.ibm.com/developerworks/cn/linux/l-cn-pythondebugger/ Debug 对于任何开发人员都是一项非常重要的技能,它能够帮助 ...

最新文章

  1. df满足条件的值修改_文科生学 Python 系列 16:泰坦尼克数据 2(缺失值处理)
  2. VS生成时复制文件到指定目录
  3. 《SqlServer性能分析一》
  4. error LNK2019: 无法解析的外部符号 __imp__inet_ntoa@4
  5. 【WPF】监听WPF的WebBrowser控件弹出新窗口的事件
  6. 六逻辑层次 职业规划案例_我如何在六个月内改变职业并找到了一名开发人员...
  7. ARTetris-AR版俄罗斯方块的源码解析
  8. 高质量C /C编程指南---附录B :C /C试题和答案
  9. openssl/ssl.h,No such file or directory
  10. C++中typedef用法说明
  11. 计算机导论第二版清华大学答案,计算机导论(第2版)课后习题答案【清华大学出版社】(13页)-原创力文档...
  12. 免费使用微软Azure进行文字转语音的三种方法!最自然接近人声的机器配音技术。
  13. 这些悬浮动效的常见玩法你都知道吗?
  14. 关于nofollow的问题
  15. Java阿凯_Java-7 面向对象(上)
  16. filecoin/lotus 官方开发文件中文翻译2019.12.17最新版本
  17. HBuilder的安装与试用
  18. 杭州旅游1-2日最佳路线
  19. 李雅普诺夫稳定性判别方法
  20. php源码首页幻灯片显示错误,织梦DEDE首页幻灯片不显示怎么办

热门文章

  1. 2022 Moonriver全球黑客松优胜项目名单
  2. 技术分享 | Hulu视频广告系统中的算法应用
  3. 使用SublimeREPL 出现系统找不到指定文件
  4. 关于USB鼠标驱动部分及问题解决
  5. css 大于号 标签_css里大于号表示什么
  6. Codeforces - Captain Flint and Treasure
  7. alipay_open_auth_token_app_response“:{“code“:“40002“,“msg“:“Invalid Arguments“,“sub_code“:“isv.inval
  8. 什么是动态评分及规则
  9. 美化我们的windows xp
  10. Pycharm里面的一些超级好用的功能——(TODO注释)用法防遗忘大法