python中debug有什么用途_史上最方便的Python Debug工具

最近在github上冒出了一个python的debug神器PySnooper,号称在debug时可以消灭print。那么该工具有哪些优点呢,如何使用该工具呢。本文就介绍该工具的优缺点和使用方式。

前言

使用python开发过程中,总是避免不了debug。传统的debug过程大致分为两种:

a)断点+单步调试。

断点+单步调试估计是用的最多的了,对于较大型项目来说,其流程大致为:先在关键的代码位置加上print语句,通过分析print的值将范围缩小,这个过程可能需要重复多次,使用print的方法,一般可以将范围缩小到一个比较完整的功能模块中;然后在可能出现bug的模块中的关键部分打上断点,进入到断点后使用单步调试,查看各变量的值是否正确,最后根据错误的变量值定位到具体的代码行,最后进行修改。

b) pdb调试。

pdb是python自带的一个包,为 python 程序提供了一种交互的源代码调试功能,主要特性包括设置断点、单步调试、进入函数调试、查看当前代码、查看栈片段、动态改变变量的值等。pdb的调试流程和1)基本差不多,其具体的使用方法大家可以网上搜一下。

传统的debug的方法的缺点包括:

a)需要在代码中添加print语句,这就改变了原有的代码;

b)在断点调试和单步调试过程中,需要保持持续的专注,一旦跳过了关键点就要从头开始。

最近在github上冒出了一个debug工具,可以解决传统debug过程中的缺点。下面一块来看看这个工具的使用和神奇之处。

Python学习交流群:835017344,这里是python学习者聚集地,有大牛答疑,有资源共享!有想学习python编程的,或是转行,或是大学生,还有工作中想提升自己能力的,正在学习的小伙伴欢迎加入学习。

1. PySnooper是什么

e5d84304d232

image

该工具使用采用装饰器的形式,将函数的运行过程以日志的形式打印到文件中,其记录了运行了哪些代码行,运行的时间及运行到当前代码时各变量的值。根据变量的变化就可以定位问题了。亲自试用该工具后,其优点可总结为以下几点:

1、无需为了查看变量的值,使用print打印变量的值,从而修改了原有的代码。

2、接口的运行过程以日志的形式保存,方便随时查看。

3、可以根据需要,设置函数调用的函数的层数,方便将注意力集中在需要重点关注的代码段。

4、多个函数的日志,可以设置日志前缀表示进行标识,方便查看时过滤。

该工具有这么多优点,那么如何使用呢,下面结合demo来介绍该工具的使用。

2. 使用方式介绍

2.1 工具安装

pip install pysnooper

2.2官方demo介绍

官方demo代码:

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)

控制台输出:

e5d84304d232

image

控制台的输出如上图,从图中可以看到,从进入到函数开始,会记录每一行代码的执行及记录新增局部变量或已有局部变量的变化,直到函数结束。以装饰器的形式使用该工具后,会将函数运行的中间结果打印出来,这样方便后续的bug定位和分析。

2.3 参数介绍

以装饰器的形式使用该工具,其包含了四个参数,参数包括output, variables, depth, prefix,如下图。

e5d84304d232

image

1、output参数。该参数指定函数运行过程中产生的中间结果的保存位置,若该值为空,则将中间结果输出到控制台。

2、variables参数。该参数是vector类型, 因为在默认情况下,装饰器只跟踪局部变量,要跟踪非局部变量,则可以通过该字段来指定。默认值为空vector。

3、depth参数。该参数表示需要追踪的函数调用的深度。在很多时候,我们在函数中会调用其他函数,通过该参数就可以指定跟踪调用函数的深度。默认值为1。

4、prefix参数。该参数用于指定该函数接口的中间结果前缀。当多个函数都使用的该装饰器后,会将这些函数调用的中间结果保存到一个文件中,此时就可以通过前缀过滤不同函数调用的中间结果。默认值为空字符串。

3. 工具应用

要使用该工具只需要理解该装饰器(snoop)的参数的含义,下面结合几个demo介绍参数的使用及对结果的影响。

3.1 output 参数使用

若使用默认参数,则将中间结果输出到控制台,若填写该参数,则将中间结果写入到该参数指定的目录下,如运行以下代码,其中间结果会保存在装饰器snoop中设置日志保存的路径中,注意这里不会自动创建目录,所以需要事先创建目录,如测试代码中填写路径后需要创建log目录。

测试代码:

import pysnooper

def add(num1, num2):

return num1 + num2

@pysnooper.snoop("./log/debug.log", prefix="--*--")

def multiplication(num1, num2):

sum_value = 0

for i in range(0, num1):

sum_value = add(sum_value, num2)

return sum_value

value = multiplication(3, 4)

运行该代码后,在./log/debug.log的内容如下:

e5d84304d232

image

从运行代码的中间结果中可以看出,文件中记录了各行代码的执行过程及局部变量的变化。在debug时,通过分析该文件,就可以跟踪每一步的执行过程及局部变量的变化,这样就能快速的定位问题所在;由于运行的中间结果保存在文件中,方便随时分析其运行的中间结果,也便于共享。

3.2 variables参数使用

在默认参数的情况下,使用该工具只能查看局变量的变化过程,当需要查看局部变量以外变量时,则可以通过variables参数进行设置,比如下方代码,在Foo类型,需要查看类实例的变量self.num1, self.num2, self.sum_value,则可以看将该变量设置当参数传入snoop的装饰器中。

测试代码:

import pysnooper

class Foo(object):

def __init__(self):

self.num1 = 0

self.num2 = 0

self.sum_value = 0

def add(self, num1, num2):

return num1 + num2

@pysnooper.snoop(output="./log/debug.log", variables=("self.num1", "self.num2", "self.sum_value"))

def multiplication(self, num1, num2):

self.num1 = num1

self.num2 = num2

sum_value = 0

for i in range(0, num1):

sum_value = self.add(sum_value, num2)

self.sum_value = sum_value

return sum_value

foo = Foo()

foo.multiplication(3, 4)

为了体现该参数的作用,这里分别使用默认参数和上述参数(代码中设置的参数)运行代码,得到的结果如下:

e5d84304d232

image

使用默认参数的结果

e5d84304d232

image

使用代码中参数的结果

从两个中间结果中可以看出,若变量不是局部变量,哪怕在函数中使用了该变量,如果不显示设置打印该变量的中间结果,则不会将该变量的中间结果打印到文件中。

3.3 depth参数使用

该参数用来指定记录函数调用层数的结果,默认值为1,若要查看多层函数调用的中间结果,则可将该参数设置为>=2。

测试代码:

import pysnooper

def add(num1, num2):

return num1 + num2

@pysnooper.snoop("./log/debug.log", depth=2)

def multiplication(num1, num2):

sum_value = 0

for i in range(0, num1):

sum_value = add(sum_value, num2)

return sum_value

value = multiplication(3, 4)

为了对比,将depth的值分别设置为1和2,其结果如下:

e5d84304d232

image

depth=1的结果

e5d84304d232

image

depth=2的结果

从上述结果中可以看出,若要查看更深层次函数调用的情况,则可以通过设置depth值进行查看。这样方便用户有选择性的查看函数的调用情况。

3.4 prefix参数使用

该参数主要用于设置中间结果的前缀,这样就可以区分不同的函数调用的中间结果,默认参数为""。

测试代码:

import pysnooper

def add(num1, num2):

return num1 + num2

@pysnooper.snoop("./log/debug.log", prefix="--*--")

def multiplication(num1, num2):

sum_value = 0

for i in range(0, num1):

sum_value = add(sum_value, num2)

return sum_value

value = multiplication(3, 4)

运行代码后的中间结果如下:

e5d84304d232

image

从结果中可以看到,中间结果的每一行都包含了prefix设置的前缀,这样便于区分不同的函数调用的中间结果。

上述的介绍为了将注意力集中到具体的参数,采取设置单一参数的形式进行介绍(output+其他单个参数)。在实际使用时,可以同时设置多个参数。使用PySnooper工具来记录函数运行的中间结果,比起传统的使用断点+单步调试,pdb等调试方法,PySnooper工具有着巨大的优势。

4. 该工具的不足之处

虽然使用debug在使用PySnooper很方便,但还是存在一些问题(以4月26号拉取代码为依据),比如:

1、无法很好的支持递归调用。

2、调用每个函数的中间结果只能保存在一个文件中,如果需要区分不同文件的结果,需要使用prefix来进行前缀标识。

3、对于跨文件函数调用,不支持记录调用函数所在的文件名。

当然PySnooper是最近在github上火起来的项目,还不够完善是正常的,相信这些不足之处后续也会得到完善,期待一个更好的PySnooper。

5. 总结

本文介绍PpySnooper的工具,先介绍了该工具是什么,相比传统debug方法的优势,然后介绍了该工具的参数及说明该参数作用的demo。最后介绍了该工具的不足之处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

能力陷阱总结

【readme】 本文总结于《能力陷阱》,感觉非常不错,有兴趣的朋友可以看下; 【1】领导者的能力陷阱 1)改变思想从行动开始; 改变做事方式,然后才能改变自己的思考方式; 2)要先在行…

Java HashMap 遍历方式性能探讨

转载自 Java HashMap 遍历方式性能探讨关于HashMap的实现这里就不展开了,具体可以参考JDK7与JDK8中HashMap的实现JDK8之前,可以使用keySet或者entrySet来遍历HashMap,JDK8中引入了map.foreach来进行遍历。原因:keySet其实是遍历了…

Raft共识算法

前提条件 Raft不考虑拜庭将军问题,即消息会延迟、丢失但不会错误。 Raft的特性 Strong leader:在 Raft 中,日志条目(log entries)只从 leader 流向其他服务器。 这简化了复制日志的管理,使得 raft 更容易…

直方图 帕累托图_如何发现现象背后的关键因素?帕累托图,质量管理的利器...

大家好:无论在日常生活还是工作中,都会发生一些事情或者结果,是我们不希望发生的。我们也希望从根本上解决掉,但有时候却无从下手,比如本来打算用来看书的时间不知道去哪里了;本来打算存款的钱也不知道去哪…

centos8上安装nginx

参考自 https://www.jianshu.com/p/9b2dd37a5af9 ; 【1】安装步骤 step1)安装nginx sudo yum install -y nginx step2)启动nginx服务 -- 开机自启动 sudo systemctl enable nginx -- 开启nginx 服务 sudo systemctl start nginx step3&am…

简单分析KafKa工作原理

架构图 Producer:Producer即生产者,消息的产生者,是消息的入口。 kafka cluster: Broker:Broker是kafka实例,每个服务器上有一个或多个kafka的实例,我们姑且认为每个broker对应一台服务器。每…

Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析

转载自 Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析网上关于 HashMap 和 ConcurrentHashMap 的文章确实不少,不过缺斤少两的文章比较多,所以才想自己也写一篇,把细节说清楚说透,尤其像 Java8 中的 ConcurrentHashMap&#…

kali mysql停止服务器_MySQL 的主从复制(高级篇)

首先要明白为什么要用 mysql 的主从复制:1–在从服务器可以执行查询工作 (即我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)2–在从主服务器进行备份,避免备份期间影响主…

centos8安装并启动tomcat9

【1】 步骤如下 step1) 下载tomcat9 step2)centos8 输入 rz命令,把tomcat9 压缩包上传到centos8 没有rz命令, 安装使用 yum -y install lrzsz step3)压缩包解压到tomcat9 step4)配置jdk环境 vim /et…

unity 3d shaderlab 开发实战详解_vue实战开发011:使用router-view嵌套路由详解

前面已经把首页的顶部header和底部的footer页面写完,现在开始写内容区域了,在写内容之前我们先要将路由配置好,不然无法在页面上查看效果,所以这里我在components目录下先建了一个home.vue文件,里面简单的写了一句“我…

go 语言 error 处理的最佳实践

今天分享 go 语言 error 处理的最佳实践,了解当前 error 的缺点、妥协以及使用时注意事项。文章内容较长,干货也多,建议收藏 什么是 error 大家都知道 error[1] 是源代码内嵌的接口类型。根据导出原则,只有大写的才能被其它源码…

请求nginx静态资源报403

【README】 请求nginx静态资源报403; 【1】原因 静态资源防止在某个家目录下,如 /root 目录下 【2】 解决方法1 nginx.conf 文件没有指定用户 # user nobody 修改为 user root; # 设置为root用户 ; 【例子】 user root; #使用r…

DDD中聚合的概念

DDD中的聚合模式是最难弄清楚的一种模式,在如何确定聚合边界这个问题上,更没有一个明确的指导原则,这导致DDD的落地比较难。不过,相信你读了这篇文章应该对聚合会有更深刻的理解。 本文分三部分来讲: 1、什么是聚合&a…

docker 打包镜像_Spring Boot2 系列教程(四十一)部署 Spring Boot 到远程 Docker 容器

不知道各位小伙伴在生产环境都是怎么部署 Spring Boot 的,打成 jar 直接一键运行?打成 war 扔到 Tomcat 容器中运行?不过据松哥了解,容器化部署应该是目前的主流方案。不同于传统的单体应用,微服务由于服务数量众多&am…

MySQL日志:binlog、事务日志(redo、undo)

事务的隔离性是通过锁实现,而事务的原子性、一致性和持久性则是通过日志实现。Mysql的日志可以分为: binlog:server层实现事务日志:包括redo log、undo log,引擎层(innodb)实现 redo log red…

vmware安装centos8步骤

【readme】 vmware 安装centos8; 【1】新建虚拟机 step1) 下载 centos8 http://download.nus.edu.sg/mirror/centos/8-stream/isos/x86_64/ 补充,通过代理服务器下载会快很多; step2)vmare,点击文件&…

并发编程 – Concurrent 用户指南

转载自 并发编程 – Concurrent 用户指南1. java.util.concurrent – Java 并发工具包Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包。这个包包含有一系列能够让 Java 的并发编程变得更加简单轻松的类。在这个包被添加以前,你需要自己去…

小微企业名录查询系统_欢迎访问辽宁小微企业名录系统

欢迎访问辽宁小微企业名录系统http://xwqy.lngs.gov.cn辽宁小微企业名录系统是小微企业扶持政策的实施公示台、集装箱,通过访问该系统网站,及时全面知晓小微企业复工复产、“个转企”等各类扶持政策。按照《国务院关于扶持小型微型企业健康发展的意见》(…

常用限流算法分析

一、计数器(固定窗口)算法 计数器算法是使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个周期开始时,进行清零,重新计数。 此算法在单机还是分布式环境下实现都非常简单&#…

nginx学习小结

nginx 【0】README 本文po处理 nginx的主要内容,包括反向代理,负载均衡,动静分离,高可用集群等; 本文引用链接: vmware安装centos8,refer2 https://blog.csdn.net/PacosonSWJTU/article/detail…