Python3之调试
程序能一次写完并正常运行的概率很小,基本不超过1%。总会有各种各样的bug需要修正。有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误的,因此,需要一整套调试程序的手段来修复bug。
第一种方法简单直接粗暴有效,就是用print()
把可能有问题的变量打印出来看看:
err3.py
def foo(s):
n=int(s)
print('>>>n=%d' % n)
return 10 / n
def main():
foo('0')
main()
运行结果,在输出中可以查找到打印的变量值
>>>n=0
Traceback (most recent call last):
File "err3.py", line 7, in <module>
main()
File "err3.py", line 6, in main
foo('0')
File "err3.py", line 4, in foo
return 10 / n
ZeroDivisionError: division by zero
用print()最大的坏处是程序调试完毕需要删除,程序到处都是print(),运行结果也包含大量垃圾信息。所以,我们又有第二种方法
do_assert.py
断言
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n def main():
foo('0') main()
assert的意思是,表达式n!=0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错
如果断言失败,assert语句本身就会抛出AssertionError
运行结果
Traceback (most recent call last):
File "do_assert.py", line 12, in <module>
main()
File "do_assert.py", line 10, in main
foo('0')
File "do_assert.py", line 6, in foo
assert n != 0, 'n is zero!'
AssertionError: n is zero!
程序中如果到处充斥着assert
,和print()
相比也好不到哪去。不过,启动Python解释器时可以用-O
参数来关闭assert
:
python3 -O do_assert.py
运行结果
Traceback (most recent call last):
File "do_assert.py", line 12, in <module>
main()
File "do_assert.py", line 10, in main
foo('0')
File "do_assert.py", line 7, in foo
return 10 / n
ZeroDivisionError: division by zero
关闭后,可以把所有的assert语句当成pass来看
logging
把print()替换成logging是第3种方式,和assert比,logging不会抛出错误,而且可以输出到文件
err4.py
import logging
#logging.basicConfig(level=logging.INFO)
s='0'
n=int(s)
logging.info('n=%d'%n)
print(10/n)
logging.info()就可以输出一段文本。运行,发现除了ZeroDivisionError,没有任何信息
Traceback (most recent call last):
File "err4.py", line 6, in <module>
print(10/n)
ZeroDivisionError: division by zero
修改增加配置
import logging
logging.basicConfig(level=logging.INFO)
s='0'
n=int(s)
logging.info('n=%d'%n)
print(10/n)
运行结果
INFO:root:n=0
Traceback (most recent call last):
File "err4.py", line 6, 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
第4种方式是启动python的调速器pdb,让程序以单步方式运行,可以随时查看运行状态
err5.py
#err5.py
s='0'
n=int(s)
print(10 / n)
启动
python3 -m pdb err5.py
以参数-m pdb启动后,pdb定位到下一步要执行的代码->s='0'
> /nas/scripts/python/learn-python3/samples/debug/err5.py(2)<module>()
-> s='0'
可以输入字母l来查看代码
(Pdb) l
1 #err5.py
2 -> s='0'
3 n=int(s)
4 print(10 / n)
输入n可以单步执行代码
(Pdb) n
> /nas/scripts/python/learn-python3/samples/debug/err5.py(3)<module>()
-> n=int(s)
> /nas/scripts/python/learn-python3/samples/debug/err5.py(4)<module>()
-> print(10 / n)
(Pdb) n
ZeroDivisionError: division by zero
> /nas/scripts/python/learn-python3/samples/debug/err5.py(4)<module>()
-> print(10 / n)
任何时候都可以输入p 加变量名查看变量
(Pdb) p s
'0'
输入q结束调试
这种通过pdb在命令行调试的方法理论上是万能的,但实在是太麻烦了,如果有一千行代码,要运行到第999行得敲多少命令啊。还好,我们还有另一种调试方法。
pdb.set_trace()
这个方法也是用pdb,但是不需要单步执行,我们只需要import pdb
,然后,在可能出错的地方放一个pdb.set_trace()
,就可以设置一个断点:
err6.py
#err6.py
import pdb
s='0'
n=int(s)
#运行到这来会自动暂停
pdb.set_trace()
print(10 / n)
运行代码,程序会自动在pdb.set_trace()
暂停并进入pdb调试环境,可以用命令p
查看变量,或者用命令c
继续运行:
(base) [root@prd-zabbix debug]# python3 err6.py
> /nas/scripts/python/learn-python3/samples/debug/err6.py(7)<module>()
-> print(10 / n)
(Pdb) p n
0
(Pdb) c
Traceback (most recent call last):
File "err6.py", line 7, in <module>
print(10 / n)
ZeroDivisionError: division by zero
IDE
如果要比较爽地设置断点、单步执行,就需要一个支持调试功能的IDE。目前比较好的Python IDE有:
Visual Studio Code:https://code.visualstudio.com/,需要安装Python插件。
PyCharm:http://www.jetbrains.com/pycharm/
另外,Eclipse加上pydev插件也可以调试Python程序。
小结
写程序最痛苦的事情莫过于调试,程序往往会以你意想不到的流程来运行,你期待执行的语句其实根本没有执行,这时候,就需要调试了。
虽然用IDE调试起来比较方便,但是最后你会发现,logging才是终极武器。
Python3之调试的更多相关文章
- vscode设置python3.7调试环境(已更新)
汇总系列:https://www.cnblogs.com/dunitian/p/4822808.html#ai CentOS安装Python3.7:https://www.cnblogs.com/do ...
- Python3 调试技巧 —— 死循环
说下Python3不使用gdb的自身调试 前情提要:服务器莫名卡死,用网上的方法用gdb,下载了很多组件,包括那个libpython.py,都没什么用,看不到堆栈,也试了保存core文件等等 大事找官 ...
- CentOS安装Python3.7
vscode设置python3.7调试环境:https://www.cnblogs.com/dotnetcrazy/p/9095793.html 先下载一下压缩包(FTP传也一样):weget htt ...
- Pycharm同步远程服务器调试
Pycharm同步远程服务器调试 1.需要准备工具 xftp:上传项目文件 xshell:连接Linux系统调试,执行命令 PyCharm:调试python代码 这些软件可以自行网上搜索下载,也可以关 ...
- =============Python安装与使用================
用文本编辑器写Python程序,然后保存为后缀为.py的文件,就可以用Python直接运行这个程序了. Python的交互模式和直接运行.py文件有什么区别呢? 直接输入python进入交互模式,相当 ...
- 人脸检测及识别python实现系列(1)——配置、获取实时视频流
人脸检测及识别python实现系列(1)——配置.获取实时视频流 1. 前言 今天用多半天的时间把QQ空间里的几篇年前的旧文搬到了这里,算是完成了博客搬家.QQ空间里还剩下一些记录自己数学学习路线的学 ...
- Python 进阶 之 协程
协程的概念级描述(与线程对比):转自知乎 链接 线程有两个必须要处理的问题:一是碰着阻塞式I\O会导致整个进程被挂起: 二是由于缺乏时钟阻塞,进程需要自己拥有调度线程的能力. 如果一种实现使得每个线程 ...
- 转 Python3 错误和异常/ Python学习之错误调试和测试
########sample 0 https://www.cnblogs.com/Simon-xm/p/4073028.html except: #捕获所有异常 except: <异常名> ...
- 11 . Python3之异常,调试和测试
12.Python3入门之异常.调试和测试 在程序运行过程中,总会遇到各种各样的错误. 有的错误是程序编写有问题造成的,比如本应该输出整数结果输出了字符串,这种错误我们通常称之为bug,bug是必须修 ...
随机推荐
- (尚016)Vue指令(11个自带指令+自定义指令)
1.Vue常用指令 1)v:text:更新元素的 textContent 2)v-html:更新元素的 innerHTML 3)v-if:如果为true,当前标签才会输出到页面 4)v-else:如果 ...
- 洛谷 P1257 平面上的最接近点对 题解
P1257 平面上的最接近点对 题目描述 给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的. 输入格式 第一行:n:2≤n≤10000 接下来n行:每行两 ...
- pycharm通过pytest运行报错:No test were found 解决
今天写代码犯了一个不应该犯的小错误,通过记录下来便于查看 1.报错代码如下: platform win32 -- Python 3.7.3, pytest-4.0.2, py-1.8.0, plugg ...
- Visual Detail Augmented Mapping for Small Aerial Target Detection(航片动态小目标检测)
1.介绍 航片里小目标占总像元数不足1%,普通目标检测算法如YOLO会有很多错误,主要原因有3点: 1.航片的无关背景占多数 2.目标大小由于飞行高度和拍摄角度不同 3.航片中的小移动目标和噪音会混淆 ...
- MySQL数据库设置表名区分大小写
使用Mysql的朋友有时候会遇到表名称不区分大小写的情况,导致导入数据或者备份数据库很麻烦. 如何设置Mysql数据库表名区分大小写呢,配置如下: 一.修改Mysql的配置文件my.ini my.in ...
- Kafka与ActiveMQ区别
Kafka 是LinkedIn 开发的一个高性能.分布式的消息系统,广泛用于日志收集.流式数据处理.在线和离线消息分发等场景.虽然不是作为传统的MQ来设计,在大部分情况,Kafaka 也可以代替原先A ...
- CodeForeces 842d Vitya and Strange Lesson ——(带lazy标记的01字典树)
给一个序列,每次操作对这个序列中的所有数异或一个x,问每次操作完以后整个序列的mex值. 做法是去重后构建01字典树,异或x就是对root加一个x的lazy标志,每次pushDown时如果lazy的这 ...
- hbase错误记录部分总结
错误1:org.apache.zookeeper.KeeperException$SessionExpiredException: KeeperErrorCode = Session expired ...
- return关键字
注意:如果一个函数的返回值类型是具体的数据类型,那么该函数就必须要保证在任意情况下都保证有返回值(除了返回值类型是void) return 关键字的作用: 1 返回数据给函数的调用者. ...
- 6、vueJs基础知识06
vue动画 transition 之前1.0版本是以 属性的形式展示的 <p transition="fade"></p> .fade-transition ...