python 调试冷知识(小结)


Posted in Python onNovember 11, 2019

对于 python 代码的调试我们通常都是使用 IDE 自带的调试功能。但是 IDE 提供的调试功能存在局限性,例如在测试服务器上调试代码,但是又不可能在测试服务器上安装 IDE 进行调试。这时我们就可以利用下面所讲解的三个工具进行调试。

零、准备调试代码

在讲解三个调试工具前,我们先编写待调试的代码。代码很简单,就是计算两个数的商。我们在编写代码的时候故意留下了除数为 0 的 bug。

def division(start, end):
  for i in range(start, end, -1):
    num1 = i
    num2 = i - 1
    result = num1 / num2
    print(result)


if __name__ == '__main__':
  division(10, 0)

一、PySnooper

PySnooper 是 Python 的第三方工具库,它可以精确的显示代码的执行时间、执行顺序和代码中的局部变量值的变化等。 PySnooper 使用方法很简单,只需要将它作为装饰器来使用即可。下面我们来看一下具体使用步骤:

安装 PySnooper

1. 在控制台输入如下命令:

pip install pysnooper

等待两秒钟后 PySnooper 安装完成。

2. 加入 PySnooper

首先需要引入 PySnooper

import pysnooper

接着在需要测试的函数上加上 pysnooper 装饰器

@pysnooper.snoop()
def division(start, end):
  for i in range(start, end, -1):
    num1 = i
    num2 = i - 1
    result = num1 / num2
    print(result)


if __name__ == '__main__':
  division(10, 0)

调试代码
在控制台输入命令:

python text.py

运行代码后,控制台输出如下内容

python 调试冷知识(小结)

python 调试冷知识(小结)

上图只截取了 PySnooper 输出日志的开头内容和最后结尾的内容。从截图中我们可以看到 PySnooper 输出了每行代码的运行顺序、运行时间和代码运行中变量值的变化,以及报错信息。在实际项目中 PySnooper 输出的日志内容会很多,在控制台查看会很不方便,这时我们可以将日志输出到本地文件中,我们只需在 PySnooper 装饰器中加入日志保存路径即可:

@pysnooper.snoop('/app/project_log.log')

一些公司对日志输出会有要求,比如每行日志要以某某字符串开头,这时只需在装饰器中加入需要字符穿即可:

@pysnooper.snoop(prefix='MyCompanyName: ')

上述所讲的都是 PySnooper 装饰器的常用参数,例如监控自定义表达式、监控底层函数、多线程等 PySnooper 同样支持,具体参数可以在官方项目文档中查看。
前面我们所讲的都是在函数上利用装饰器来监控整个函数,但是在实际项目中往往一个函数内容会很多,如果监控整个函数会导致输出的日志过多,这时我们就可以利用 PySnooper 的局部监控功能来监控函数中需要监控的代码片段。现在我们来修改一下代码,只监控输出的值:

import pysnooper

def division(start, end):
  for i in range(start, end, -1):
    with pysnooper.snoop():
      num1 = i
      num2 = i - 1
      result = num1 / num2
    print(result)


if __name__ == '__main__':
  division(10, 0)

上述代码运行后我们就会发现输出的内容少了很多。

二、Better-exceptions

Better-exceptions 同样是 Python 的第三方工具库,它出现的原因是其实很简单就是“美化异常信息”(是不是感觉作者很任性)。 Better-exceptions 主要使用了 Python 的 sys 模块的 excepthook 方法,这个方法在当系统抛出异常时,解释器就会调用它,同时传递三个参数:异常类、异常实例和 traceback 对象,这就说明我们可以重写这个方法来捕获系统异常。但是,因为我们可以重写 excepthook 方法来捕获系统异常,因此 Better-exceptions 对与 Web 框架来说是不起任何作用的,因为 Web 框架都已经处理了系统抛出的异常,不会再以 hook 的方式触发 Better-exceptions 。下面我们就来看一下该怎么用。

安装 Better-exceptions

首先在控制台输入如下命令:

pip install better-exceptions

等待两秒钟后 Better-exceptions 安装完成。

接着我们在控制台输入如下代码,来设置环境变量:

setx BETTER_EXCEPTIONS 1

调试代码
在控制台输入命令:

python text.py

代码运行后,控制台输出如下图:

python 调试冷知识(小结)

从上面的图我们可以看到,Better-exceptions 对异常代码进行了着色,并对产生异常的变量值进行了输出。通过这两项内容我们就可以很快捷的看到具体报错位置和报错原因。

这里有需要注意的地方就是,在 Windows 系统下输出的日志会存在乱码问题,这是因为 Better-exceptions 的编码格式造成的。要解决这个问题我们只需要修改 better-exceptions 目录下的 encoding.py 文件,讲文件中的 ENCODING = locale.getpreferredencoding()修改为 ENCODING = 'utf-8'即可。

三、PDB

PDB 是 Python 内置的模块,我们可以利用 PDB 设置断点和跟踪调试。 PDB 的使用不需要再安装第三方插件,只需要在命令行输入如下命令:

python -m pdb Test.py

命令执行后将会进入 PDB 调试模式。如果需要在代码中加入断点,只需要在需要加入断点的位置加入 pdb.set_trace()即可。当进入到 PDB 模式后,输入 c 就可以从当前断点直接跳转到下一个断点,如果后续没有断点,则会将剩余代码执行完。当然,如果需要单步执行代码,在控制台输入 s 指令,但是有时主函数会调用大量的其他函数,这时在命令行输入 n 就可以只在主函数中执行单步调试。除了上述指令外,PDB 还有其他指令,如下表:

指令 说明
l 显示所有代码
n 执行下一条代码
c 执行当前断点后面的代码,知道代码执行完毕
b x 在代码的第X行设置断点
clear 清除全部断点
s 单步执行
s function_name 进入 function_name 函数内部执行
q 退出PDB
a 打印所有参数值
p 打印指定变量值
r 忽略剩余断点,将剩余代码执行完毕

四、总结

我们讲解了 PySnooper 、Better-exceptions 和 PDB 的用法,这三种方法一般都使用在服务器上,这里我推荐使用Better-exceptions,因为它对代码的侵入性很小,几乎不需要改变代码。

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 计算两个日期相差多少个月实例代码
May 24 Python
python处理csv数据动态显示曲线实例代码
Jan 23 Python
pycharm: 恢复(reset) 误删文件的方法
Oct 22 Python
Python实现对特定列表进行从小到大排序操作示例
Feb 11 Python
python pexpect ssh 远程登录服务器的方法
Feb 14 Python
python datetime中strptime用法详解
Aug 29 Python
基于Python实现拆分和合并GIF动态图
Oct 22 Python
opencv-python 提取sift特征并匹配的实例
Dec 09 Python
浅谈python中频繁的print到底能浪费多长时间
Feb 21 Python
Python图像处理库PIL的ImageFilter模块使用介绍
Feb 26 Python
django 读取图片到页面实例
Mar 27 Python
python实现测试工具(一)——命令行发送get请求
Oct 19 Python
通过 Django Pagination 实现简单分页功能
Nov 11 #Python
python机器学习实现决策树
Nov 11 #Python
Python SQLAlchemy入门教程(基本用法)
Nov 11 #Python
django中间键重定向实例方法
Nov 10 #Python
Java文件与类动手动脑实例详解
Nov 10 #Python
python语言线程标准库threading.local解读总结
Nov 10 #Python
Python 脚本拉取 Docker 镜像问题
Nov 10 #Python
You might like
php二分法在IP地址查询中的应用
2008/08/12 PHP
php 404错误页面实现代码
2009/06/22 PHP
jQuery中的RadioButton,input,CheckBox取值赋值实现代码
2014/02/18 PHP
PHP动态编译出现Cannot find autoconf的解决方法
2014/11/05 PHP
laravel Task Scheduling(任务调度)在windows下的使用详解
2019/10/22 PHP
用ADODB.Stream转换
2007/01/22 Javascript
判断目标是否是window,document,和拥有tagName的Element的代码
2010/05/31 Javascript
javascript实现ecshop搜索框键盘上下键切换控制
2015/03/18 Javascript
JS中的hasOwnProperty()和isPrototypeOf()属性实例详解
2016/08/11 Javascript
BootStrap按钮标签及基本样式
2016/11/23 Javascript
node.js中的事件处理机制详解
2016/11/26 Javascript
Javascript oop设计模式 面向对象编程简单实例介绍
2016/12/13 Javascript
详解AngularJs HTTP响应拦截器实现登陆、权限校验
2017/04/11 Javascript
Bootstrap实现各种进度条样式详解
2017/04/13 Javascript
vue中使用iview自定义验证关键词输入框问题及解决方法
2018/03/26 Javascript
Layui table field初始化加载时进行隐藏的方法
2019/09/19 Javascript
vue element-ul实现展开和收起功能的实例代码
2020/11/25 Vue.js
[00:52]DOTA2齐天大圣预告片
2016/08/13 DOTA
Python中Class类用法实例分析
2015/11/12 Python
关于PyCharm安装后修改路径名称使其可重新打开的问题
2020/10/20 Python
CSS3属性 line-clamp控制文本行数的使用
2020/03/19 HTML / CSS
一个基于canvas的移动端图片编辑器的实现
2020/10/28 HTML / CSS
德国最大的拼图在线商店:Puzzle.de
2016/12/17 全球购物
美国知名生活购物网站:Goop
2017/11/03 全球购物
Tech21美国/加拿大:英国NO.1防摔保护壳品牌
2018/01/20 全球购物
银行见习期自我鉴定
2014/01/29 职场文书
酒店员工检讨书
2014/02/18 职场文书
《一本男孩子必读的书》教学反思
2014/02/19 职场文书
《日月潭》教学反思
2014/02/28 职场文书
高中竞选班长演讲稿
2014/04/24 职场文书
银行求职信模板
2015/03/20 职场文书
教师调动申请报告
2015/05/18 职场文书
网络研修心得体会
2016/01/08 职场文书
30岁前绝不能错过的10本书
2019/08/08 职场文书
你有一份《诚信考试承诺书》待领取
2019/11/13 职场文书
MySQL数据库之内置函数和自定义函数 function
2022/06/16 MySQL