0. 标题
Python库IceCream介绍:print调试的颠覆者
代码语言:txt复制作者: quantgalaxy@outlook.com
blog: https://blog.csdn.net/quant_galaxy
1. Why: 为什么要抛弃print调试
1.1 使用print调试的问题
调试代码的时候,最简单直接的方式,就是使用print()函数来把变量打印到输出中,查看问题。
但是,使用print()有很多的不便之处:
- print()语句需要自己构建输出的语句和格式,并且在调试完成后,需要手动删除print()语句。
- 如果你需要打印多个变量,需要做很多重复的事情,自己组织好提示信息,不然输出的是一串没有提示的结果。
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库,目标通过最少的代码使打印调试更具可读性。
它有以下特点:
- 可以同时打印表达式,变量名称,以及对应的值。
- 智能化的配置输出信息,减少了调试时候的输入信息。
- 可以适配打印python数据结构。
- 可以突出显示语法。
通过两个简单的例子来认识下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