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

print是我们平时写些python小工具时,最常用的调试工具。

因为开发代码时,常常通过print将执行流程、变量的值以及其他关键信息输出到控制台来观察,

以便了解程序执行情况和调试bug

但是,print的输出过于简单,在输出变量内容,函数调用,执行过程等相关信息时,

往往需要自己手动去补充很多的输出信息的说明,否则很容易搞不清输出的内容是什么。

而今天介绍的icecream,为我们提供了一种更加优雅和强大的方式来调试代码。

它不仅可以自动格式化输出内容,自动添加必要的描述信息,而且使用起来也比print更加简单。

1. 安装

通过pip安装:

bash 复制代码
pip install icecream

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

2. 使用示例

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

2.1. 调试变量

首先是调试变量,这也是用的最多的场景。

开发中,我们常常需要将变量打印出来以确认是否正确赋值。

print方式:

python 复制代码
# 数值和字符串
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)

icecream方式:

python 复制代码
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)

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

  1. 输入效率更高,因为icprint更容易输入,只有两个字母。
  2. 自动带上变量名称,一眼看出打印的是哪个变量的值
  3. 变量名称和值用不同的颜色显示,容易区分

2.2. 调试函数输出

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

python 复制代码
def func(a: int, b: int):
    return a + b

print(func(2, 3))

icecream方式:

python 复制代码
from icecream import ic

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

ic(func(2, 3))

2.3. 调试执行过程

接下来是调试执行过程,当代码中有很多分支判断时,我们常常是在各个分支中print不同的数字,

然后用不同的输入看看代码是否按照预期的那样进入不同而分支。

比如,下面构造一个多分支判断的函数,看看分别用printicecream是如何调试的。

print方式:

python 复制代码
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)

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

icecream方式:

python 复制代码
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)

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

2.4. 定制化输出

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

首先,我们注意到通过ic()打印的内容都有一个ic | 前缀,

实际使用时,我们希望将其替换为和项目相关的文字。

比如,我基于manim做个小动画,希望打印的前缀是 manim |

python 复制代码
from icecream import ic

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

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

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

python 复制代码
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")

除了定义前缀,还可以在输出时添加我们需要的信息。

比如,我们希望打印字符串列表字典变量时,顺带输出其长度信息,不用在再去额外打印其长度信息。

python 复制代码
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)

从打印内容可以看出,字符串列表字典 变量后面有长度len信息,

而数值变量和元组,则没有打印长度len信息。

同样,在数据分析时,也可以通过定制,

让我们打印pandasDataFrame内容时,顺带打印出其shape信息。

python 复制代码
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)

3. 总结

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

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

相关推荐
数据智能老司机6 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机7 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机7 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机7 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i7 小时前
drf初步梳理
python·django
每日AI新事件7 小时前
python的异步函数
python
这里有鱼汤8 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python
databook17 小时前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室18 小时前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
倔强青铜三19 小时前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试