扔掉print,用icecream来调试你的代码

2024-03-25 23:12

本文主要是介绍扔掉print,用icecream来调试你的代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

print是我们平时写些python小工具时,最常用的调试工具。因为开发代码时,常常通过print将执行流程、变量的值以及其他关键信息输出到控制台来观察,以便了解程序执行情况和调试bug

但是,print的输出过于简单,在输出变量内容,函数调用,执行过程等相关信息时,往往需要自己手动去补充很多的输出信息的说明,否则很容易搞不清输出的内容是什么。

而今天介绍的icecream,为我们提供了一种更加优雅和强大的方式来调试代码。它不仅可以自动格式化输出内容,自动添加必要的描述信息,而且使用起来也比print更加简单。

1. 安装

通过pip安装:

pip install icecream

安装之后可以通过打印其版本来验证是否安装成功。

image.png

2. 使用示例

下面看看icecream如何替换开发中常见的各种print场景。

2.1. 调试变量

首先是调试变量,这也是用的最多的场景。开发中,我们常常需要将变量打印出来以确认是否正确赋值。

print方式:

# 数值和字符串
i = 100
f = 3.14
s = "abc"
print(i, f, s)# 元组,列表和字典
t = (10, 20, 30)
l = [1, 2, 3]
d = {"A": "abc", "B": 100}
print(t, l, d)
print(t[0], l[1], d["A"])# 类
class c:name = "ccc"addr = "aa bb cc"print(c.name, c.addr)

image.png

icecream方式:

from icecream import ic# 数值和字符串
i = 100
f = 3.14
s = "abc"
ic(i, f, s)# 元组,列表和字典
t = (10, 20, 30)
l = [1, 2, 3]
d = {"A": "abc", "B": 100}
ic(t, l, d)
ic(t[0], l[1], d["A"])# 类
class c:name = "ccc"addr = "aa bb cc"ic(c.name, c.addr)

image.png

通过比较,可以看出icecream的几个优势:

  1. 输入效率更高,因为icprint更容易输入,只有两个字母。

  2. 自动带上变量名称,一眼看出打印的是哪个变量的值

  3. 变量名称和值用不同的颜色显示,容易区分

2.2. 调试函数输出

调试函数输出也是常用的,如果把函数调用也看做一个变量的话,其实这个和上面打印变量类似。print方式:

def func(a: int, b: int):return a + bprint(func(2, 3))

image.png

icecream方式:

from icecream import icdef func(a: int, b: int):return a + bic(func(2, 3))

image.png

2.3. 调试执行过程

接下来是调试执行过程,当代码中有很多分支判断时,我们常常是在各个分支中print不同的数字,然后用不同的输入看看代码是否按照预期的那样进入不同而分支。比如,下面构造一个多分支判断的函数,看看分别用printicecream是如何调试的。

print方式:

def pflow(a: float, b: float):print(1)evaluate = ""if a > 90 and b > 90:print(2)evaluate = "优"elif a > 80 and b > 80:print(3)evaluate = "良"elif a > 70 and b > 70:print(4)evaluate = "中"else:print(5)evaluate = "及格"if a < 60 or b < 60:print(6)evaluate = "不合格"print(7)return evaluatepflow(98, 92)
print("---------------------")
pflow(75, 65)
print("---------------------")
pflow(88, 85)
print("---------------------")
pflow(77, 72)
print("---------------------")
pflow(98, 55)

image.png

需要根据数字去看看分支执行是否符合预期。

icecream方式:

from icecream import icdef flow(a: float, b: float):ic()evaluate = ""if a > 90 and b > 90:ic()evaluate = "优"elif a > 80 and b > 80:ic()evaluate = "良"elif a > 70 and b > 70:ic()evaluate = "中"else:ic()evaluate = "及格"if a < 60 or b < 60:ic()evaluate = "不合格"ic()return evaluateflow(98, 92)
ic()
flow(75, 65)
ic()
flow(88, 85)
ic()
flow(77, 72)
ic()
flow(98, 55)

image.png

简简单单的一个**ic()**,会把执行的代码位置和函数名称,执行时间等打印出来。

2.4. 定制化输出

最后,icecream还提供了强大的定制化接口,可以按照自己的需要调整输出的内容。

首先,我们注意到通过ic()打印的内容都有一个ic |前缀,实际使用时,我们希望将其替换为和项目相关的文字。比如,我基于manim做个小动画,希望打印的前缀是 manim |

from icecream import icdef cfg():ic.configureOutput(prefix="manim -> | ")ic("something")
cfg()
ic("something")

image.png

前缀还可以是动态的,比如用执行时间作为前缀:

from icecream import icdef cfg():import timetime_prefix = lambda: time.strftime("%Y-%m-%d %H:%M:%S -> | ", time.localtime())ic.configureOutput(prefix=time_prefix)ic("something")
cfg()
ic("something")

image.png

除了定义前缀,还可以在输出时添加我们需要的信息。比如,我们希望打印字符串列表字典变量时,顺带输出其长度信息,不用在再去额外打印其长度信息。

from icecream import icdef add_info(obj):if isinstance(obj, str) or isinstance(obj, list) or isinstance(obj, dict):return f"{obj}(len:{len(obj)})"return repr(obj)ic.configureOutput(argToStringFunction=add_info)
i = 100
f = 3.14
s = "abc"
ic(i, f, s)t = (10, 20, 30)
l = [1, 2, 3]
d = {"A": "abc", "B": 100}
ic(t, l, d)

image.png

从打印内容可以看出,字符串列表字典变量后面有长度len信息,而数值变量和元组,则没有打印长度len信息。

同样,在数据分析时,也可以通过定制,让我们打印pandasDataFrame内容时,顺带打印出其shape信息。

import pandas as pddef add_info(obj):if isinstance(obj, pd.DataFrame):return f"{obj}\nshape:{obj.shape}"return repr(obj)df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
ic(df)

image.png

3. 总结

总的来说,icecream 提供了一种更加现代和高效的调试方式,让我们更关注需要打印的内容,不用去操心打印的格式。

文章转载自:wang_yb

原文链接:https://www.cnblogs.com/wang_yb/p/18092154

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

这篇关于扔掉print,用icecream来调试你的代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/846560

相关文章

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

java之Objects.nonNull用法代码解读

《java之Objects.nonNull用法代码解读》:本文主要介绍java之Objects.nonNull用法代码,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录Java之Objects.nonwww.chinasem.cnNull用法代码Objects.nonN

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤