调试是开发过程中不可避免的一个环节,在Python中我们使用print、logging、assert等方法进行调试既简单又实用,但毕竟有其局限性。今天这篇文章为大家带来三个工具,其中有Python的内置模块也有第三方库,它们提供了调试代码所需的大部分常用功能,将极大的提升我们的开发和bug排除效率。

1.PDB

pdb是Python中的一个内置模块,启用pdb后可以对代码进行断点设置和跟踪调试。为了演示方便,我们准备一个样例程序pdb_test.py:

def countnumber(number):  for i in range(number):    print(i)

if __name__ == '__main__':  countnumber(10)

之后在终端中输入python -m pdb pdb_test.py命令,进入pdb的调试模式:

这时我们就可以通过各种命令控制代码执行或者查看当前变量,例如l可以查看所有代码,n是执行下一步代码,p可以查看当前变量等等,需要注意的是命令n只会执行主程序中的代码,如果想要单步执行子函数中的代码,需要使用s指令,调试效果如下:

可以看到,通过s指令(如果只想在主函数中单步执行可以使用n)和p指令,我们控制程序单步运行并实时查看了相关变量。但是单步执行毕竟是一种效率非常低下的调试方式,尤其当代码量比较大的时候更是噩梦,这时就需要用到pdb的set_trace()方法,我们对样例程序pdb_test.py做一点修改:

import pdbdef countnumber(number):  for i in range(number):    print(i)    pdb.set_trace()

if __name__ == '__main__':  countnumber(10)

pdb.set_trace()的作用就是在代码中设置断点,在pdb调试模式下,使用c命令就会直接跳转到下一个断点位置,如果之后没有其他断点就会执行完全部代码,调试效果如下:

除了上面提到的几个指令以外,pdb还有其他一些比较常用的命令(见下表),综合使用基本能够满足日常的调试需求。

2.Better-exceptions

better-exceptions是一个Python第三方库,作者对他的定义是“使异常信息更加美观和详尽”。在正式使用之前先说下这个库的安装:

  • 第一步,使用pip install better_exceptions安装better-exceptions库;
  • 第二步,使用export BETTER_EXCEPTIONS=1(Linux / OSX)或setx BETTER_EXCEPTIONS 1(Windows)设置环境变量。

现在就可以正常使用better-exceptions进行调试了,为了演示效果更加明显,我们对上文中的代码稍作修改作为本次的样例程序better_test.py:

def divisionnumber(number, div):  for i in range(div):    print(number / i)

if __name__ == '__main__':  divisionnumber(10, 10)

很明显,上面这段代码在执行过程中会因为分母为0而抛出异常,现在我们执行python better_test.py,看看启用了better-exceptions后的异常信息是什么样子的:

从上面这幅图可以看出better-exceptions对异常信息的修改主要体现在两个方面:

  • 一是对产生异常的代码进行了颜色标注;

  • 二是对产生异常的代码中的相关变量值进行了输出(包括函数等对象);

这样一来,很多时候我们只需要根据better-exceptions输出的辅助信息就能判断产生异常的位置和原因,而不必像以前一样再次查看源代码并观察运行结果,正如作者所说:Pretty and more helpful。但是,过多的信息输出也会有问题,那就是当代码层级结构比较复杂的时候,better-exceptions输出的辅助信息可能会非常之多,就比如上面的divisionnumber函数,他所在的地址信息多数时候我们并不关心,为了屏蔽这些“垃圾”信息,我们可以在代码中加一行:

better_exceptions.MAX_LENGTH = XXX

XXX是允许显示的最大字符长度,比如这里设置为10,再来运行better_test.py这个程序就会是下面的结果:

可以看到,对函数divisionnumber的注释只显示了最开始的"除了上面提到的功能之外,better-exceptions还可以和logging还有django无缝接入,这使得它的应用更加灵活,关于这方面内容大家可以查看项目文档。还有一点需要提醒大家,如果你是在windows下使用,可能会出现下图中的乱码问题,这是由于better-exceptions的内设编码格式所导致的。

解决的办法是在安装后,对better_exceptions目录下的encoding.py文件第10行代码进行如下修改:

# 原代码:ENCODING = locale.getpreferredencoding()# 修改为:ENCODING = 'utf-8'

3.PySnooper

PySnooper也是一个Python的第三方库,他的特点是能够精准的显示每条代码的执行顺序、执行时间以及随之带来的局部变量的改变等等。值得一提的是,作为一个发布不满半年的库,PySnooper在github上已经达到了1.2W星,其受欢迎程度可见一斑。

PySnooper的使用可以说是非常的方便,直接在代码中以装饰器的形式调用就可以了。当然在引用前你得使用pip install pysnooper或者conda install -c conda-forge pysnooper安装这个库。我们还是举一个例子来进行演示,样例代码如下:

import pysnooperimport random@pysnooper.snoop()def foo():    lst = []    for i in range(10):        lst.append(random.randrange(1, 1000))    lower = min(lst)    upper = max(lst)    mid = (lower + upper) / 2    print(lower, mid, upper)foo()

在上面这段代码中,我们先是生成10个1到1000之间的随机数,然后计算他们之中的最大最小值和中位数,唯一的不同在于第三行多了一条语句@pysnooper.snoop(),我们运行以下代码,发现除了正常的print结果之外,多了许多内容(内容太多,下面只显示一部分):

19:51:57.704857 call        16 def foo():19:51:57.705860 line 17     lst = []New var:....... lst = []19:51:57.705860 line 18     for i in range(10):New var:....... i = 019:51:57.705860 line 19         lst.append(random.randrange(1, 1000))Modified var:.. lst = [758]19:51:57.705860 line 18     for i in range(10):Modified var:.. i = 1

....................

19:51:57.706818 line 22     upper = max(lst)New var:....... upper = 92719:51:57.706818 line 23     mid = (lower + upper) / 2New var:....... mid = 552.019:51:57.706818 line 24     print(lower, mid, upper)19:51:57.706818 return      24     print(lower, mid, upper)Return value:.. None

这都是PySnooper跟踪监控的结果,正如上面所说,他准确记录的每条代码的运行时间、顺序以及相关的变量值。作为一个星标1.2W+的项目,PySnooper的功能肯定不会这么简单,@pysnooper.snoop()中是可以接收参数的,比如我们觉得输出内容太多,可以考虑把信息记录到log日志中,这个功能只需要加一个log文件定位参数就能搞定:

@pysnooper.snoop('file.log')

@pysnooper.snoop()支持的参数还有很多,分别对应了不同的功能,例如监控自定义表达式、监控底层函数、支持多线程等等,详见项目文档。此外,pysnooper还支持局部监控,一般来说我们写的代码都比较长,而需要监控的只是其中的一小部分,这时候就可以把需要监控的代码放到一个block里。我们修改下刚才的代码,只对计算最大最小值和中位数的部分进行监控,修改后的代码如下:

import pysnooperimport randomdef foo():    lst = []    for i in range(10):        lst.append(random.randrange(1, 1000))    with pysnooper.snoop():      lower = min(lst)      upper = max(lst)      mid = (lower + upper) / 2    print(lower, mid, upper)foo()

运行之后发现监控信息精简了很多:

New var:....... lst = [562, 341, 552, 353, 628, 302, 430, 188, 955, 108]New var:....... i = 920:02:47.359272 line 21       lower = min(lst)New var:....... lower = 10820:02:47.359272 line 22       upper = max(lst)New var:....... upper = 95520:02:47.360269 line 23       mid = (lower + upper) / 2

使用with pysnooper.snoop()模式依然保留了对各种参数的支持,个人认为这种模式更加符合实践需求。


小结:今天介绍了三个不借助IDE就能方便使用的调试工具,三个工具的调试思路和适用场景也各不相同,大家可以根据需要灵活选用。不过话说回来,我个人最喜欢的还是PySnooper,你最喜欢哪一款呢?近期热门:四年完成400万行Python代码检查,甚至顺手写了个编译器转行Python最好看一下这篇文章

零基础必读热门:

零基础学了8个月的Python,到底有啥感悟菜鸟如何提升Python编程水平,老码农良心推荐强烈建议|转行Python最好看一下这篇文章

qdebug 调试 输出乱码_Python里三个最高逼格的调试神器相关推荐

  1. python调试神器_Python里三个最高逼格的调试神器

    调试是开发过程中不可避免的一个环节,在Python中我们使用print.logging.assert等方法进行调试既简单又实用,但毕竟有其局限性.今天这篇文章为大家带来三个工具,其中有Python的内 ...

  2. Python里三个最高逼格的调试神器

    调试是开发过程中不可避免的一个环节,在Python中我们使用print.logging.assert等方法进行调试既简单又实用,但毕竟有其局限性.今天这篇文章为大家带来三个工具,其中有Python的内 ...

  3. python好用-Python里三个好用的调试神器

    1.PDB pdb是Python中的一个内置模块,启用pdb后可以对代码进行断点设置和跟踪调试.为了演示方便,我们准备一个样例程序pdb_test.py: def countnumber(number ...

  4. 用python输入三个整数输出最大值_python 判断三个数字中的最大值实例代码

    python 判断三个数字中的最大值,具体代码如下所示: #判断三个数中最大值 n1= int(input('please enter the firest number:')) n2 = int(i ...

  5. VSCode_ 配置C++调试和运行环境_VSCode输出乱码问题

    1.安装VSCode插件和MingGW 用VSCode运行C语言和C++还是比较方便的,虽然说没有VS那种直接集成的大环境,但是平时自己做些小规模的测试运行都已经足够了 VSCode中支持C/C++运 ...

  6. vscode 调试.net core 2.0 输出乱码解决方法

    vscode 调试.net core 2.0 输出乱码解决方法 参考文章: (1)vscode 调试.net core 2.0 输出乱码解决方法 (2)https://www.cnblogs.com/ ...

  7. python输出结果乱码_python输出结果乱码怎么办

    Python中文乱码的原因,Python中文乱码是由于Python在解析网页时默认用Unicode去解析,而大多数网站是utf-8格式的,并且解析 出来之后,python竟然再以Unicode字符格式 ...

  8. linux/windows_vscode_配置mingw的C/C++环境(by official doc)/一些可能遇到的问题和对策)/vscode中文输出乱码问题

    文章目录 preface for windows for linux references 官网提供的配置教程(vscode+cpp): 官方文档简述 目录名要求 相关配置文件及含义 从windows ...

  9. CUDA C编程(三十八)CUDA调试

    这部分内容主要是介绍一些专门为CUDA应用程序设计的调试工具和方法.设计这些工具和方法的目的是让我们可以在代码运行的时候检查应用程序.接下来,代码检查将被分成两个独立但是相关的部分,分别是内核调试和内 ...

最新文章

  1. Eureka服务器端启动时报错:Connection refused :connect
  2. 一个go1.9.x 编译器内联引起的栈信息错乱的问题分析
  3. python maketrans_Python maketrans()方法 - Python 教程 - 自强学堂
  4. idea无法启动Tomcat
  5. python画版图_基于mask-RCNN的版图分析,MaskRCNN,版面
  6. Arcgis Engine 添加一个Symbol符号样式步骤
  7. 如何轻松除掉肠道废物
  8. SCRT804安装教程
  9. 福利来了,axure8.1注册码
  10. android HttpClient获取json数据
  11. oracle 获得节假日,Oracle 计算两个日期间时间排除非工作日及非工作时间
  12. MVVM和MCV模式
  13. 在IDEA中集成Jenkins插件 解决Missing or bad crumb data异常
  14. 使用计算机的时正确的开机步骤,电脑启动时选择启动模式的方法步骤图
  15. QT QGraphicsItem飞舞的蝴蝶
  16. 实例2:python操作Excel文件 - 插入列、分列、删除列、移动位置
  17. 到店维修要注意以下三点
  18. STM32HAL库学习之路(八):MG90S舵机应用
  19. java jquery愤怒的小鸟_如何做html5山寨版愤怒的小鸟
  20. Okhttp MVC

热门文章

  1. c#实现文件批处理:剪切、复制、删除、改名、分类等
  2. 贺利坚老师汇编课程42笔记:DIV除法指令
  3. Nginx篇--解读nginx配置
  4. Python基本语法(一)
  5. UOJ #117. 欧拉回路
  6. Mybatis 单独项目
  7. Javascript项目
  8. JS+CSS实现Dock menu(MacOS菜单导航效果)
  9. [转载] python eval序列化函数
  10. [转载] python函数分为哪几种_python常用函数