Python库IceCream介绍:print调试的颠覆者

2023-10-03 17:38:40 浏览数 (1)

0. 标题

Python库IceCream介绍:print调试的颠覆者

代码语言:txt复制
作者: quantgalaxy@outlook.com   
blog: https://blog.csdn.net/quant_galaxy  

1. Why: 为什么要抛弃print调试

1.1 使用print调试的问题

调试代码的时候,最简单直接的方式,就是使用print()函数来把变量打印到输出中,查看问题。

但是,使用print()有很多的不便之处:

  1. print()语句需要自己构建输出的语句和格式,并且在调试完成后,需要手动删除print()语句。
  2. 如果你需要打印多个变量,需要做很多重复的事情,自己组织好提示信息,不然输出的是一串没有提示的结果。
代码语言:python代码运行次数:0复制
var_1 = 1
var_2 = 2
print(var_1)
print(var_2)

# 1
# 2

上面的语句,我们打印了两个变量,如果调试的内容很多,就无法准确定位到具体的变量和语句。

当然,我们也可以加入更多的信息,方便打印变量的信息:

代码语言:python代码运行次数:0复制
var_1 = 1
var_2 = 2
print("var_1 =", var_1)
print("var_2 =", var_2)

# var_1 = 1
# var_2 = 2

从上面的例子中我们可以看出,如果我们要打印很多变量,或者打印更多的信息,就需要我们在print函数中记录更多的信息,

这对于调试过程来说,很多都是重复性的工作。

另一种情况是,一个项目的代码有许多文件组成,如果用print调试,为了调试方便需要打印文件名,又是一个额外的信息处理。

基于上面的原因,print虽然是一个可以直接使用的调试方法,但是对于调试来说,也是一个费时费力,并且不又好的方法。

IceCream就是专门用于debug的print方式。很好的解决了上面的问题。

2. Why: 为什么选用IceCream

github项目地址:IceCream

IceCream是一个专门用来打印调试信息的Python库,目标通过最少的代码使打印调试更具可读性。

它有以下特点:

  1. 可以同时打印表达式,变量名称,以及对应的值。
  2. 智能化的配置输出信息,减少了调试时候的输入信息。
  3. 可以适配打印python数据结构。
  4. 可以突出显示语法。

通过两个简单的例子来认识下icecream。

输出表达式和结果值:

代码语言:python代码运行次数:0复制
from icecream import ic

def foo(i):
    return i   333

ic(foo(123))

# output: ic| foo(123): 456

智能匹配内置的数据结构信息:

代码语言:python代码运行次数:0复制
from icecream import ic

d = {'key': {1: 'one'}}
ic(d)

class klass():
    attr = 'yep'
ic(klass.attr)

# ic| d: {'key': {1: 'one'}}
# ic| klass.attr: 'yep'

上面两个例子,简单的展示下ic的输出。

可以看到,icecream相比print,可以用更简单的方式,输出更多的信息,方便调试和定位问题。

3. How: 如何使用IceCream

3.1 安装

代码语言:python代码运行次数:0复制
pip install icecream

3.2 打印变量和值

只要把变量放到ic()中即可:

代码语言:python代码运行次数:0复制
from icecream import ic

var_1 = 2
ic(var_1)

# ic| var_1: 2

3.3 打印表达式和值

和打印变量类似:

代码语言:python代码运行次数:0复制
from icecream import ic

def func(num):
    return num * 2

ic(func(3))

# ic| func(3): 6

3.4 打印内置数据类型

代码语言:python代码运行次数:0复制
from icecream import ic

a = [1, 2, 3, 4]
b = {1:"A", 2:"B", 3:"C"}

ic(a)
ic(b[1])

# ic| a: [1, 2, 3, 4]
# ic| b[1]: 'A'

3.5 检查执行情况

很多时候,我们使用print()在条件语句中检查到底执行了哪个条件,进入了哪个循环语句,比如:

代码语言:python代码运行次数:0复制
def func(input_num):
    if input_num == 1:
        print("If Executed!")
        ...

    else:
        print("Else Executed!")
        ...

使用ic的时候,我们可以直接在不同的语句中添加ic(),就可以智能打印被调用的条件,比如:

代码语言:python代码运行次数:0复制
from icecream import ic

def func(input_num):
    if input_num == 1:
        ic()
        pass

    else:
        ic()
        pass

func(2)

# ic| 2047037218.py:9 in func() at 13:50:04.291

输出语句会自动定位到被执行的行号。

代码语言:txt复制
作者: quantgalaxy@outlook.com   
blog: https://blog.csdn.net/quant_galaxy  

3.6 打印返回值

代码语言:python代码运行次数:0复制
from icecream import ic

a = 6
def half(i):
    return i / 2
ic(half(ic(a)))

# ic| a: 6
# ic| half(ic(a)): 3.0

上面的语句,可以自动的把函数返回值和表达式的值都打印出来。

3.7 自定义输出的格式

上面举例中的ic输出内容,都是默认的格式,我们还可以通过ic.configureOutput()来自定义输出的信息。

输出更多的信息:

代码语言:python代码运行次数:0复制
from icecream import ic

# ic.configureOutput(prefix, outputFunction, argToStringFunction, includeContext, contextAbsPath)
ic.configureOutput(includeContext=True, contextAbsPath=True)

i = 3
ic(i)

# ic| /absolute/path/to/example.py:6 in <module> i: 3

把输出重定位到另外的函数中:

代码语言:python代码运行次数:0复制
import logging
from icecream import ic

def warn(s):
	logging.warning(s)
	
ic.configureOutput(outputFunction=warn)
ic('eep')

# WARNING:root:ic| /absolute/path/to/example.py:8 in <module> 'eep': 'eep'

输出格式的参数含义:

  • prefix:每行输出的前缀信息,默认是“ic|”。
  • outputFunction:把每个ic的输出结果,传给调用的这个输出函数中。默认是stderr。
  • argToStringFunction:把ic的参数,逐个传入调用的字符串处理函数中,自定义输出的格式。默认是pprint。
  • includeContext:打印文件名,行号,父函数信息。
  • contextAbsPath:打印执行文件的绝对路径。

如果把上面的参数重置为默认值,使用下面的语句:

代码语言:python代码运行次数:0复制
# DEFAULT_PREFIX = 'ic| '
# DEFAULT_OUTPUT_FUNCTION = colorizedStderrPrint
# DEFAULT_ARG_TO_STRING_FUNCTION = pprint.pformat

from icecream import DEFAULT_OUTPUT_FUNCTION

ic.configureOutput(outputFunction=DEFAULT_OUTPUT_FUNCTION)

3.8 如何在整个项目范围内使用

在整个项目内使用icecream,不需要每个python文件都import,可以在项目的root file文件中,执行install即可:

代码语言:python代码运行次数:0复制
from icecream import install
install()

3.9 如何在项目中关闭调试

第一种方式就是通过搜索的方式,删除左右的ic语句,这种方式不可逆,并不推荐。

第二种方式,是通过函数disable停用,通过enable函数启用:

代码语言:python代码运行次数:0复制
from icecream import ic

ic(1)

ic.disable()
ic(2)

ic.enable()
ic(3)

# ic| 1
# ic| 3

4. 作者信息

代码语言:txt复制
作者: quantgalaxy@outlook.com   
blog: https://blog.csdn.net/quant_galaxy  

0 人点赞