首页 > 其他分享 >扔掉print,用icecream来调试你的代码

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

时间:2024-03-24 11:14:39浏览次数:26  
标签:obj evaluate 打印 icecream print ic 调试

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 + b

print(func(2, 3))

image.png

icecream方式:

from icecream import ic

def func(a: int, b: int):
    return a + b

ic(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 evaluate

pflow(98, 92)
print("---------------------")
pflow(75, 65)
print("---------------------")
pflow(88, 85)
print("---------------------")
pflow(77, 72)
print("---------------------")
pflow(98, 55)

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

icecream方式:

from icecream import ic

def 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 evaluate

flow(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 ic

def cfg():
    ic.configureOutput(prefix="manim -> | ")

ic("something")
cfg()
ic("something")

image.png

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

from icecream import ic

def cfg():
    import time

    time_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 ic

def 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 pd

def 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 提供了一种更加现代和高效的调试方式,让我们更关注需要打印的内容,不用去操心打印的格式。

除了pythonicecream还有一系列其他语言的接口:

标签:obj,evaluate,打印,icecream,print,ic,调试
From: https://www.cnblogs.com/wang_yb/p/18092154

相关文章

  • 关于使用PZ6808L开发板,调试USART3的问题分析
    首先,写代码方面相信,大家都可以搞定,网上也有很多人写的程序,这里关于如何驱动USART3,就不进行赘述了。关于这款开发板RS232模块,是给F4使用的,但是他留了两个接线柱,就是F1的USART3的两个接口。接下来就是接线的问题,如下图,将这个4个接线柱,两两交叉进行连接,跳线帽肯定搞不了,如下图......
  • Qt/C++通用跨平台Onvif工具/支持海康大华宇视华为天地伟业等/云台控制/预置位管理/工
    一、前言在安防视频监控行业,Onvif作为国际标准,几乎主要的厂商都支持,不仅包含了国内的厂商,也包括主要的国际厂商,由于有了这个标准的存在,使得不同设备不同安防平台之间,能够接入各个厂家的硬件设备,互通有无,你中有我我中有你,实现良性竞争。ONVIF是一个全球性的开放式行业协议,其目标是......
  • 基于ssm的风景文化管理平台,旅游信息管理系统,附源码+数据库+论文+PPT,包远程安装调试
    1、项目介绍根据木里风景文化管理平台的功能需求,进行系统设计。前台功能:用户进入系统可以实现首页,旅游公告,景区,景区商品,景区美食,旅游交通工具,红黑榜,个人中心,后台管理,购物车等进行操作;后台主要是管理员,管理员功能包括首页,个人中心,用户管理,旅游公告管理,景区管理,景区商品管理,门......
  • 基于ssm的农业信息管理系统,农资信息管理系统,附源码+数据库+论文+PPT,包远程安装调试
    1、项目介绍考虑到实际生活中在农业信息管理方面的需要以及对该系统认真的分析,将系统权限按管理员,种植户和用户这三类涉及用户划分。(1)管理员功能需求管理员登陆后,主要模块包括首页,个人中心,用户管理,种植户管理,农业技术管理,农产品类型管理,农资类型管理,农资产品管理,农产品管理,......
  • 毕业设计3283基于微信的选修课考勤签到小程序的设计与实现【源代码+文档+调试+讲解视
    摘要本文旨在设计一个基于微信的选修课考勤签到小程序,实现服务器端、教师模块和学生模块的功能需求。通过详细的功能需求分析、数据库设计、界面设计以及测试和优化,本文将为该小程序的开发提供全面的指导。开发技术微信小程序;JSP技术;JAVA语言;MYSQL数据库微信小程序微信......
  • 3.Go 语言 定义变量、fmt 包、Print、Println、Go 语言注释
    Go语言定义变量、fmt包、Print、Println、Printf、Go语言注释1、Go语言定义变量这里我们为了演示代码期间给大家先简单介绍一下变量,后面的教程还会详细讲解。关于变量:程序运行过程中的数据都是保存在内存中,我们想要在代码中操作某个数据时就需要去内存上找到这个变量,但是......
  • C语言中的printf和sprintf的用法及区别
    sprintf函数是C语言中用于格式化输出到字符串的函数。它的原型如下:intsprintf(char*buffer,constchar*format,[argument]…);str:指向存储输出结果的字符数组的指针。format:格式化字符串,包含要输出的文本和格式说明符。[argument]:可变参数列表,用于提供要插入格式化......
  • 系统开发中的快速测试与调试策略
    在日新月异的软件开发领域中,如何高效地进行测试和调试工作,确保软件质量,成为了每个开发团队必须面对的重要问题。本文旨在探讨如何在系统开发过程中实现快速测试和调试,以提高开发效率,降低项目风险。答案:在系统开发过程中实现快速测试和调试,关键在于采用自动化测试工具、构建......
  • 毕业设计3257 基于微信小程序的校园招聘信息管理系统的设计与实现【源代码+文档+调试+
    摘要本文介绍了一个基于微信小程序的校园招聘信息管理系统的设计与实现。该系统旨在为学生和企业提供一个便捷、高效的招聘信息交流平台。服务器端负责数据管理,包括用户、简历、岗位、应聘信息和论坛帖子的管理;学生和企业客户端则提供注册登录、信息浏览、搜索、发布、管理......
  • c/c++|gdb 单点调试 | 多点调试|查看栈中信息|具体变量
    设置断点,有什么好处,废话就不说了,可以去看手册设置断点,参考bxxx.cpp:n某个源文件的某行bfunc1调试某个函数编译g++test_gdb_watch.cpp-g设置断点bpowerr出现报错Missingseparatedebuginfos,use:debuginfo-installglibc-2.17-326.el7_9.x86_64libg......