关于PySnooper 永远不要使用print进行调试的问题


Posted in Python onMarch 04, 2021

PySnooper 是一个非常方便的调试器。如果您正在试图弄清楚为什么您的Python代码没有按照您的预期去做,您会希望使用具有断点和监视功能的成熟Debug工具,但是许多Debug工具配置起来非常麻烦。

现在,有了PySnooper,您并不需要配置那么复杂的Debug工具,就能够完成对整个代码的分析。它能告诉您哪些代码正在运行,以及局部变量的值是什么。

其实,PySnooper 就是替代了一行一行print的重复性工作,给你的代码一个pysnooper装饰器,它能自动识别到语句和变量并将其值print出来:

import pysnooper
 
@pysnooper.snoop()
def number_to_bits(number):
  if number:
    bits = []
    while number:
      number, remainder = divmod(number, 2)
      bits.insert(0, remainder)
    return bits
  else:
    return [0]
 
number_to_bits(6)

效果如下:

Source path:... 1.py
Starting var:.. number = 6
23:03:35.990701 call     4 def number_to_bits(number):
23:03:35.991699 line 5   if number:
23:03:35.991699 line 6     bits = []
New var:....... bits = []
23:03:35.991699 line 7     while number:
23:03:35.991699 line 8       number, remainder = divmod(number, 2)
Modified var:.. number = 3
New var:....... remainder = 0
23:03:35.991699 line 9       bits.insert(0, remainder)
Modified var:.. bits = [0]
23:03:36.004664 line 7     while number:
23:03:36.005661 line 8       number, remainder = divmod(number, 2)
Modified var:.. number = 1
Modified var:.. remainder = 1
23:03:36.005661 line 9       bits.insert(0, remainder)
Modified var:.. bits = [1, 0]
23:03:36.007657 line 7     while number:
23:03:36.007657 line 8       number, remainder = divmod(number, 2)
Modified var:.. number = 0
23:03:36.008655 line 9       bits.insert(0, remainder)
Modified var:.. bits = [1, 1, 0]
23:03:36.008655 line 7     while number:
23:03:36.009651 line 10     return bits
23:03:36.009651 return   10     return bits
Return value:.. [1, 1, 0]
Elapsed time: 00:00:00.020945

可以看到,它将每一行变量的值都输出到屏幕上,方便你调试代码。

仅仅需要写一行代码—使用装饰器就可以实现这个方便的调试功能,比起一行行写print,这可方便多了。

0.安装模块

使用这个模块,你只需要使用Pip安装PySnooper:

pip install pysnooper

接下来讲讲这个模块其他好用的功能:

1.支持日志文件

如果你觉得print到屏幕上不方便,还可以将其输出到log文件中,你只需要将装饰器那一行改为:

@pysnooper.snoop('/my/log/file.log')

2.读取局外变量或其他表达式

如果你想读取在装饰器作用范围以外的变量或者表达式的值,还可以使用watch参数:

@pysnooper.snoop(watch=('foo.bar', 'self.x["whatever"]'))

3.如果你不想用装饰器,也可以用上下文的形式调试

没错,装饰器有限定的使用条件,使用起来比较局限,因此pysnooper还支持使用 with 的上下文形式:

import pysnooper
import random
 
def 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:....... i = 9
New var:....... lst = [681, 267, 74, 832, 284, 678, ...]
09:37:35.881721 line 10     lower = min(lst)
New var:....... lower = 74
09:37:35.882137 line 11     upper = max(lst)
New var:....... upper = 832
09:37:35.882304 line 12     mid = (lower + upper) / 2
74 453.0 832
New var:....... mid = 453.0
09:37:35.882486 line 13     print(lower, mid, upper)
Elapsed time: 00:00:00.000344

当我们只需要调试部分代码的时候,这个上下文形式的调试方法非常方便。

此外,PySnooper还有许多更强大的用法,大家可以看他们的高级使用文档:

https://github.com/cool-RR/PySnooper/blob/master/ADVANCED_USAGE.md

到此这篇关于PySnooper 永远不要使用print进行调试的文章就介绍到这了,更多相关PySnooper print调试内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
pyv8学习python和javascript变量进行交互
Dec 04 Python
python连接mongodb操作数据示例(mongodb数据库配置类)
Dec 31 Python
详细讲解用Python发送SMTP邮件的教程
Apr 29 Python
Python实现读写sqlite3数据库并将统计数据写入Excel的方法示例
Aug 07 Python
python 用lambda函数替换for循环的方法
Jun 09 Python
mac下pycharm设置python版本的图文教程
Jun 13 Python
PyQt5事件处理之定时在控件上显示信息的代码
Mar 25 Python
python是怎么被发明的
Jun 15 Python
Python操作Elasticsearch处理timeout超时
Jul 17 Python
Python生成器generator原理及用法解析
Jul 20 Python
matplotlib教程——强大的python作图工具库
Oct 15 Python
python库sklearn常用操作
Aug 23 Python
pip/anaconda修改镜像源,加快python模块安装速度的操作
Mar 04 #Python
Pytorch实现WGAN用于动漫头像生成
Mar 04 #Python
基于PyInstaller各参数的含义说明
Mar 04 #Python
解决Pyinstaller打包软件失败的一个坑
Mar 04 #Python
selenium+python自动化78-autoit参数化与批量上传功能的实现
Mar 04 #Python
解决PDF 转图片时丢文字的一种可能方式
Mar 04 #Python
pandas数据分组groupby()和统计函数agg()的使用
Mar 04 #Python
You might like
php 用sock技术发送邮件的函数
2007/07/21 PHP
PHP中的float类型使用说明
2010/07/27 PHP
php获取系统变量方法小结
2015/05/29 PHP
Symfony2函数用法实例分析
2016/03/18 PHP
[原创]PHP字符串中插入子字符串方法总结
2016/05/06 PHP
php使用curl详细解析及问题汇总
2016/08/11 PHP
浅谈Laravel核心解读之Console内核
2018/12/02 PHP
优秀js开源框架-jQuery使用手册(1)
2007/03/10 Javascript
js 点击按钮弹出另一页,选择值后,返回到当前页
2010/05/26 Javascript
jQuery之选项卡的简单实现
2014/02/28 Javascript
简介JavaScript中的push()方法的使用
2015/06/09 Javascript
jQuery判断多个input file 都不能为空的例子
2015/06/23 Javascript
深入学习JavaScript的AngularJS框架中指令的使用方法
2016/03/05 Javascript
JQuery在循环中绑定事件的问题详解
2016/06/02 Javascript
angularJS+requireJS实现controller及directive的按需加载示例
2017/02/20 Javascript
基于Node.js的WebSocket通信实现
2017/03/11 Javascript
详解webpack + react + react-router 如何实现懒加载
2017/11/20 Javascript
解决vue2.0动态绑定图片src属性值初始化时报错的问题
2018/03/14 Javascript
JS引用传递与值传递的区别与用法分析
2018/06/01 Javascript
vue中使用mxgraph的方法实例代码详解
2019/05/17 Javascript
Node.js 的 GC 机制详解
2019/06/03 Javascript
在Echarts图中给坐标轴加一个标识线markLine
2020/07/20 Javascript
[01:05:56]2018DOTA2亚洲邀请赛3月29日 小组赛A组 Newbee VS VG
2018/03/30 DOTA
python的几种开发工具介绍
2007/03/07 Python
在Python中使用异步Socket编程性能测试
2014/06/25 Python
Python迭代用法实例教程
2014/09/08 Python
Python线程的两种编程方式
2015/04/14 Python
Python中进程和线程的区别详解
2017/10/29 Python
Python聊天室程序(基础版)
2018/04/01 Python
使用Python 正则匹配两个特定字符之间的字符方法
2018/12/24 Python
SneakerStudio英国:最佳运动鞋商店
2019/05/22 全球购物
银行贷款收入证明
2014/10/17 职场文书
2014年资料员工作总结
2014/11/18 职场文书
客服专员岗位职责
2015/02/10 职场文书
Python函数中的不定长参数相关知识总结
2021/06/24 Python
详细介绍MySQL中limit和offset的用法
2022/05/06 MySQL