Python代码调试
作者:黎智煊,叩丁狼高级讲师。本文为原创文章,转载请注明出处。
调试
程序能一次写完并正常运行的概率很小,基本不超过1%。总会有各种各样的bug需要修正。有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误的,因此,需要一整套调试程序的手段来修复bug。
- 第一种方法简单直接粗暴有效,就是用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
后,debug
和info
就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。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代码调试相关推荐
- 转:Python 代码调试技巧
Python 代码调试技巧 转载于:https://www.cnblogs.com/kira2will/p/4254754.html
- 【QA】Python代码调试之解决Segmentation fault (core dumped)问题
Python代码调试之解决Segmentation fault 问题 问题描述 排查过程 1. 定位错误, 2. 解决办法 参考资料 问题描述 Python3执行某一个程序时,报Segmentatio ...
- python代码调试中间变量_Python代码调试的那些“最少且必要”技巧
原标题:Python代码调试的那些"最少且必要"技巧 异常处理模块能帮助我们在运行期间处理异常信息,但Python代码还有更为基础的错误--语法错误和逻辑错误. 语法错误相对简单, ...
- Python代码调试方法
对于每个程序开发者来说,调试几乎是必备技能.常用Pycharm编辑器里的方法有Print大法.log大法,但缺少类似Matlab的变量区,给代码调试带来不便,特别是在有函数的情况下,变量无法实时查看. ...
- python代码调试快捷键_6. Pycharm的传参、快捷键、执行代码、调试模式
1.通过pycharm给python程序传递参数 脚本传入的参数.多个参数这个大家都比较熟悉,就不多说了 Pycharm如何传入参数? 先来认识python的参数: sys.argv[0]脚本本身 s ...
- Eclipse中调试Python代码--调试FWTools2.4.7中的gdal_retile.py
Eclipse中调试Python代码 Gdal_retile.py是用于对遥感影像创建金字塔,近期本人想读懂改程序中的代码.读懂代码的较好方式就是单步调试,但是由于之前没有学过Python语言,不但对 ...
- Python 代码调试二三事
♚ 作者王维栋,网易游戏运维与基础架构部,产品软件设计师,专注于智能监控.性能优化等领域. 本文来自<网易游戏运维平台 (neteasegameops)>微信公众号的投稿,隶属于网易游戏运 ...
- eclipse 下安装PyDev并导入faster rcnn python代码调试
Python在算法研究应用非常广泛,最近要研究faster rcnn的python代码,就得学习python,所以就需要一个趁手的工具来看python代码,否则只是用文本编译器找代码实在是太影响效率了 ...
- 简单实用,Python代码调试利器
❝ 本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes ❞ 1 简介 尽管有那么多花里胡哨的debug工 ...
- 【转】Python 代码调试技巧
原文网址:http://www.ibm.com/developerworks/cn/linux/l-cn-pythondebugger/ Debug 对于任何开发人员都是一项非常重要的技能,它能够帮助 ...
最新文章
- df满足条件的值修改_文科生学 Python 系列 16:泰坦尼克数据 2(缺失值处理)
- VS生成时复制文件到指定目录
- 《SqlServer性能分析一》
- error LNK2019: 无法解析的外部符号 __imp__inet_ntoa@4
- 【WPF】监听WPF的WebBrowser控件弹出新窗口的事件
- 六逻辑层次 职业规划案例_我如何在六个月内改变职业并找到了一名开发人员...
- ARTetris-AR版俄罗斯方块的源码解析
- 高质量C /C编程指南---附录B :C /C试题和答案
- openssl/ssl.h,No such file or directory
- C++中typedef用法说明
- 计算机导论第二版清华大学答案,计算机导论(第2版)课后习题答案【清华大学出版社】(13页)-原创力文档...
- 免费使用微软Azure进行文字转语音的三种方法!最自然接近人声的机器配音技术。
- 这些悬浮动效的常见玩法你都知道吗?
- 关于nofollow的问题
- Java阿凯_Java-7 面向对象(上)
- filecoin/lotus 官方开发文件中文翻译2019.12.17最新版本
- HBuilder的安装与试用
- 杭州旅游1-2日最佳路线
- 李雅普诺夫稳定性判别方法
- php源码首页幻灯片显示错误,织梦DEDE首页幻灯片不显示怎么办
热门文章
- 2022 Moonriver全球黑客松优胜项目名单
- 技术分享 | Hulu视频广告系统中的算法应用
- 使用SublimeREPL 出现系统找不到指定文件
- 关于USB鼠标驱动部分及问题解决
- css 大于号 标签_css里大于号表示什么
- Codeforces - Captain Flint and Treasure
- alipay_open_auth_token_app_response“:{“code“:“40002“,“msg“:“Invalid Arguments“,“sub_code“:“isv.inval
- 什么是动态评分及规则
- 美化我们的windows xp
- Pycharm里面的一些超级好用的功能——(TODO注释)用法防遗忘大法