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实现计算文件夹下.h和.cpp文件的总行数
Apr 23 Python
在Python的Flask中使用WTForms表单框架的基础教程
Jun 07 Python
基于Python的XSS测试工具XSStrike使用方法
Jul 29 Python
对Python中DataFrame按照行遍历的方法
Apr 08 Python
对python抓取需要登录网站数据的方法详解
May 21 Python
Python3中bytes类型转换为str类型
Sep 27 Python
详解利用Python scipy.signal.filtfilt() 实现信号滤波
Jun 05 Python
PyTorch的深度学习入门之PyTorch安装和配置
Jun 27 Python
pytorch使用指定GPU训练的实例
Aug 19 Python
vscode写python时的代码错误提醒和自动格式化的方法
May 07 Python
tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this T
Jun 22 Python
python在package下继续嵌套一个package
Apr 14 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
德生PL550的电路分析
2021/03/02 无线电
PHP 5.0对象模型深度探索之属性和方法
2008/03/27 PHP
PHP图片等比例缩放生成缩略图函数分享
2014/06/10 PHP
php通过array_unshift函数添加多个变量到数组前端的方法
2015/03/18 PHP
thinkPHP连接sqlite3数据库的实现方法(附Thinkphp代码生成器下载)
2016/05/27 PHP
JavaScript下利用fso判断文件是否存在的代码
2010/12/11 Javascript
javascript的tab切换原理与效果实现方法
2015/01/10 Javascript
Javascript中实现trim()函数的两种方法
2015/02/04 Javascript
JavaScript中的Math.LN2属性用法详解
2015/06/12 Javascript
JavaScript 七大技巧(二)
2015/12/13 Javascript
jQuery中delegate()方法的用法详解
2016/10/13 Javascript
vuejs router history 配置到iis的方法
2018/09/20 Javascript
用npm安装vue和vue-cli,并使用webpack创建项目的方法
2018/09/28 Javascript
vue-cli脚手架搭建的项目去除eslint验证的方法
2018/09/29 Javascript
使用koa-log4管理nodeJs日志笔记的使用方法
2018/11/30 NodeJs
浅谈Vue.js中如何实现自定义下拉菜单指令
2019/01/06 Javascript
微信小程序发送短信验证码完整实例
2019/01/07 Javascript
js实现图片放大并跟随鼠标移动特效
2019/01/18 Javascript
python实现井字棋游戏
2020/03/30 Python
TensorFlow深度学习之卷积神经网络CNN
2018/03/09 Python
python使用PIL和matplotlib获取图片像素点并合并解析
2019/09/10 Python
Pytorch 实现focal_loss 多类别和二分类示例
2020/01/14 Python
关于python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13)
2020/10/19 Python
HTML5之WebGL 3D概述(下)—借助类库开发及框架介绍
2013/01/31 HTML / CSS
HTML5 直播疯狂点赞动画实现代码 附源码
2020/04/14 HTML / CSS
Manduka官网:瑜伽垫、瑜伽毛巾和服装
2018/07/02 全球购物
英国打印机墨盒销售网站:Ink Factory
2019/10/07 全球购物
2014两会学习心得:榜样精神伴我行
2014/03/17 职场文书
反邪教警示教育方案
2014/05/13 职场文书
带刀到教室的检讨书
2014/10/04 职场文书
领导班子三严三实心得体会
2014/10/13 职场文书
2014年个人思想工作总结
2014/11/27 职场文书
培训计划通知
2015/07/15 职场文书
2016年教师寒假学习心得体会
2015/10/09 职场文书
如何在Mac上通过docker配置PHP开发环境
2021/05/29 PHP
javascript函数式编程基础
2021/09/15 Javascript