前言
在程序开发过程中,代码的运行往往会和我们预期的结果有所差别。于是,我们需要清楚代码运行过程中到底发生了什么?代码哪些模块运行了,哪些模块没有运行?输出的局部变量是什么样的?很多时候,我们会想到选择使用成熟、常用的IDE使用断点和watches调试程序,或者更为基础的print函数、log打印出局部变量来查看是否符合我们预期的执行效果。但是这些方法都有一个共同的弱点--效率低且繁琐,本文就介绍一个堪称神器的Python/ target=_blank class=infotextkey>Python调试工具PySnooper,能够大大减少调试过程中的工作量。
装饰器
装饰器(Decorators)是Python里一个很重要的概念,它能够使得Python代码更加简洁,用一句话概括:装饰器是修改其他函数功能的函数。PySnooper的调用主要依靠装饰器的方式,所以,了解装饰器的基本概念和使用方法更有助于理解PySnooper的使用。在这里,我先简单介绍一下装饰器的使用,如果精力有限,了解装饰器的调用方式即可。
对于Python,一切都是对象,一个函数可以作为一个对象在不同模块之间进行传递,举个例子,
其实这就是装饰器的核心所在,它们封装一个函数,可以用这样或那样的方式来修改它。换一种方式表达上述调用,可以用@+函数名来装饰一个函数。
此外,在调用装饰器时还可以给函数传入参数:
另外,装饰器本身也可以接收参数,
上面讲述的就是Python装饰器的一些常用方法。
Pysnooper
调试程序对于大多数开发者来说是一项必不可少的工作,当我们想要知道代码是否按照预期的效果在执行时,我们会想到去输出一下局部变量与预期的进行比对。目前大多数采用的方法主要有以下几种:
但是这些方法有着无法忽视的弱点:
"PySnooper is a poor man's DEBUGger."
有了PySnooper,上述问题都迎刃而解,因为PySnooper实在太简洁了,目前在Github已经10k+star。
前面花了一段篇幅讲解装饰器其实就是为了PySnooper做铺垫,PySnooper的调用就是通过装饰器的方式进行使用,非常简洁。
PySnooper的调用方式就是通过@pysnooper.snoop的方式进行使用,该装饰器可以传入一些参数来实现一些目的,具体如下:
参数描述None输出日志到控制台filePath输出到日志文件,例如'log/file.log'prefix给调试的行加前缀,便于识别watch查看一些非局部变量表达式的值watch_explode展开值用以查看列表/字典的所有属性或项depth显示函数调用的函数的snoop行
安装
使用pip安装,
或者使用conda安装,
使用
先写一个简单的例子,
这是最简单的使用方法,从上述输出结果可以看出,PySnooper输出信息主要包括以下几个部分:
也就是说,把我们日常DEBUG所需要的主要信息都输出出来了。
上述结果输出到控制台,还可以把日志输出到文件,
image
image.gif
在函数调用过程中,PySnooper还能够显示函数的层次关系,使得一目了然,
从上述输出结果可以看出,函数one与函数two的输出缩进层次一目了然。
除了缩进之外,PySnooper还提供了参数prefix给debug信息添加前缀的方式便于识别,
参数watch可以用于查看一些非局部变量,例如,
参数watch_explode可以展开字典或者列表显示它的所有属性值,对比一下它和watch的区别,
可以看出watch_explode能够展开字典的属性值。
另外还有参数depth显示函数中调用函数的snoop行,默认值为1,参数值需要大于或等于1。