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是必须修 ...
随机推荐
- Error Permission denied when running brew cleanup
Error Permission denied when running brew cleanup When I try to run `brew cleanup` I get: Warning: S ...
- asp.net之大文件分段上传、断点续传
ASP.NET上传文件用FileUpLoad就可以,但是对文件夹的操作却不能用FileUpLoad来实现. 下面这个示例便是使用ASP.NET来实现上传文件夹并对文件夹进行压缩以及解压. ASP.NE ...
- P2709 小B的询问 (莫队板子)
题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...
- LibreOJ #527. 「LibreOJ β Round #4」框架
二次联通门 : LibreOJ #527. 「LibreOJ β Round #4」框架 /* LibreOJ #527. 「LibreOJ β Round #4」框架 %% xxy dalao 对于 ...
- 题解 CF1097F 【Alex and a TV Show】
妙妙题-- 这道题这要求%2的个数,肯定有什么性质 于是我们想到了用\(bitset\)来处理 由于三操作有\(gcd\),于是我们又想到用反演来解决 我们回忆一下反演的柿子 设\(f(x)\)为x出 ...
- Android中活动被回收了怎么办
当一个活动进入到了停止状态,是有可能被系统回收的.按下返回键的时候,活动被重新创建一次,但是里面的数据就没办法重现: 这时Activity中提供了一个onSaveInstanceState()回调方法 ...
- Spark(五十二):Spark Scheduler模块之DAGScheduler流程
导入 从一个Job运行过程中来看DAGScheduler是运行在Driver端的,其工作流程如下图: 图中涉及到的词汇概念: 1. RDD——Resillient Distributed Datase ...
- Linux测试硬盘读性能的常用工具-hdparm
通常情况下可以使用fdisk.df等命令查看硬盘的分区情况以及当前已使用空间大小.剩余空间大小等信息.但是如果要查看硬盘的硬件信息如 硬盘型号.序列号.已运行时间等信息该用什么工具查看呢? 在Linu ...
- 【转载】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
原文链接:https://www.cnblogs.com/lixinjie/p/10811219.html 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使 ...
- 阿里物联网平台(一)Windows系统+VS2017 模拟设备端接入
https://blog.csdn.net/panwen1111/article/details/88365636 一.阿里物联网平台 平台地址:https://account.aliyun.com ...