百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

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

off999 2024-11-23 20:38 16 浏览 0 评论

原创: 大刘 菜鸟学Python


调试是开发过程中不可避免的一个环节,在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 pdb
def 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的注释只显示了最开始的"<function"这几个字符。

除了上面提到的功能之外,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 pysnooper
import 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 = 0
19: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 = 927
19:51:57.706818 line 23 mid = (lower + upper) / 2
New var:....... mid = 552.0
19: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 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:....... lst = [562, 341, 552, 353, 628, 302, 430, 188, 955, 108]
New var:....... i = 9
20:02:47.359272 line 21 lower = min(lst)
New var:....... lower = 108
20:02:47.359272 line 22 upper = max(lst)
New var:....... upper = 955
20:02:47.360269 line 23 mid = (lower + upper) / 2


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


小结:

今天介绍了三个不借助IDE就能方便使用的调试工具,三个工具的调试思路和适用场景也各不相同,大家可以根据需要灵活选用。不过话说回来,我个人最喜欢的还是PySnooper,你最喜欢哪一款呢?

最后,我自己是一名从事了多年开发的Python老程序员,辞职目前在做自己的Python私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的Python学习干货,可以送给每一位喜欢Python的小伙伴,想要获取的可以关注我的头条号并在后台私信我:Python,即可免费获取。

相关推荐

阿里云国际站ECS:阿里云ECS如何提高网站的访问速度?

TG:@yunlaoda360引言:速度即体验,速度即业务在当今数字化的世界中,网站的访问速度已成为决定用户体验、用户留存乃至业务转化率的关键因素。页面加载每延迟一秒,都可能导致用户流失和收入损失。对...

高流量大并发Linux TCP性能调优_linux 高并发网络编程

其实主要是手里面的跑openvpn服务器。因为并没有明文禁p2p(哎……想想那么多流量好像不跑点p2p也跑不完),所以造成有的时候如果有比较多人跑BT的话,会造成VPN速度急剧下降。本文所面对的情况为...

性能测试100集(12)性能指标资源使用率

在性能测试中,资源使用率是评估系统硬件效率的关键指标,主要包括以下四类:#性能测试##性能压测策略##软件测试#1.CPU使用率定义:CPU处理任务的时间占比,计算公式为1-空闲时间/总...

Linux 服务器常见的性能调优_linux高性能服务端编程

一、Linux服务器性能调优第一步——先搞懂“看什么”很多人刚接触Linux性能调优时,总想着直接改配置,其实第一步该是“看清楚问题”。就像医生看病要先听诊,调优前得先知道服务器“哪里...

Nginx性能优化实战:手把手教你提升10倍性能!

关注△mikechen△,十余年BAT架构经验倾囊相授!Nginx是大型架构而核心,下面我重点详解Nginx性能@mikechen文章来源:mikechen.cc1.worker_processe...

高并发场景下,Spring Cloud Gateway如何抗住百万QPS?

关注△mikechen△,十余年BAT架构经验倾囊相授!大家好,我是mikechen。高并发场景下网关作为流量的入口非常重要,下面我重点详解SpringCloudGateway如何抗住百万性能@m...

Kubernetes 高并发处理实战(可落地案例 + 源码)

目标场景:对外提供HTTPAPI的微服务在短时间内收到大量请求(例如每秒数千至数万RPS),要求系统可弹性扩容、限流降级、缓存减压、稳定运行并能自动恢复。总体思路(多层防护):边缘层:云LB...

高并发场景下,Nginx如何扛住千万级请求?

Nginx是大型架构的必备中间件,下面我重点详解Nginx如何实现高并发@mikechen文章来源:mikechen.cc事件驱动模型Nginx采用事件驱动模型,这是Nginx高并发性能的基石。传统...

Spring Boot+Vue全栈开发实战,中文版高清PDF资源

SpringBoot+Vue全栈开发实战,中文高清PDF资源,需要的可以私我:)SpringBoot致力于简化开发配置并为企业级开发提供一系列非业务性功能,而Vue则采用数据驱动视图的方式将程序...

Docker-基础操作_docker基础实战教程二

一、镜像1、从仓库获取镜像搜索镜像:dockersearchimage_name搜索结果过滤:是否官方:dockersearch--filter="is-offical=true...

你有空吗?跟我一起搭个服务器好不好?

来人人都是产品经理【起点学院】,BAT实战派产品总监手把手系统带你学产品、学运营。昨天闲的没事的时候,随手翻了翻写过的文章,发现一个很严重的问题。就是大多数时间我都在滔滔不绝的讲理论,却很少有涉及动手...

部署你自己的 SaaS_saas如何部署

部署你自己的VPNOpenVPN——功能齐全的开源VPN解决方案。(DigitalOcean教程)dockovpn.io—无状态OpenVPNdockerized服务器,不需要持久存储。...

Docker Compose_dockercompose安装

DockerCompose概述DockerCompose是一个用来定义和管理多容器应用的工具,通过一个docker-compose.yml文件,用YAML格式描述服务、网络、卷等内容,...

京东T7架构师推出的电子版SpringBoot,从构建小系统到架构大系统

前言:Java的各种开发框架发展了很多年,影响了一代又一代的程序员,现在无论是程序员,还是架构师,使用这些开发框架都面临着两方面的挑战。一方面是要快速开发出系统,这就要求使用的开发框架尽量简单,无论...

Kubernetes (k8s) 入门学习指南_k8s kubeproxy

Kubernetes(k8s)入门学习指南一、什么是Kubernetes?为什么需要它?Kubernetes(k8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序。它...

取消回复欢迎 发表评论: