不再使用 Print 来Debug了, IceCream 来了!

开发 前端
用print()语句进行调试是一种混乱的、不优雅的方法。将输出映射到其相应的调试语句是很混乱的。此外,它需要额外的手动格式化来理解输出。

写在前面

在编程过程中,Bug几乎是不可避免的。其实大部分程序员花了大量的时间进行Debug(调试),以使他们的代码没有Bug。​

图片

在调试时,最常用的方法无疑是选择使用print()语句来了解 pipeline 流程以及发现bug。

然而,使用print()有许多注意事项,例如:

  • 打印语句通常是为了向用户显示一个输出。如果程序员使用print()​进行调试,在调试结束后,程序员应该谨慎地只删除那些特定的print()语句,这些语句是用来调试的。
  • 通常,在调试期间,你可能会一个接一个地打印多个变量。在这种情况下,程序员必须手动格式化输出以增强其可读性。
var_1 = 1
var_2 = 2
print(var_1)
print(var_2)
1
2

上面,我们打印了两个变量。虽然在这里我们知道第一个变量是var_1​,第二个是var_2,但随着变量数量的增加,可能需要你在代码和输出之间来回寻找,以找出哪个输出对应于哪个变量。

当然,我们可以打印更多的细节,像下面这样,但这只是增加了你的工作,如果我们一直在做像这样的工作,不就需要996了。

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()(至少对我来说)成为最糟糕的调试选项。

值得庆幸的是,在Python中有一个很好的替代方案 —— IceCream[1] 🍦!

IceCream

IceCream是一个Python库,它使Debug不费吹灰之力,并能用最少的代码查看调试结果。

它常用的功能包括打印表达式、变量名、函数名、行号、文件名等等。

安装 IceCream

你可以使用 pip​来安装 icecream库。

pip install icecream

导入IceCream

使用这个库的标准惯例是导入ic模块,如下所示。

from icecream import ic

开始使用IceCream

使用 IceCream 库就像 print 语句一样简单。你需要把 print()​ 替换为 ic()。就是这样。

ic(var_1)
ic(var_2)
ic| var_1: 1
ic| var_2: 2

注意区别!ic()不仅打印值,而且还打印所传递的变量的名称。

IceCream 不仅仅局限于一个变量。相反,你可以在函数、类等方面使用它。

def func(num):
return num * 2
ic(func(3))
ic| func(3): 6

超酷!它打印了方法的名称(func​),传递的参数(3​)和输出(6)。

每一个进入ic()​方法的表达式​都会被打印出来,同时还有表达式的数值,如下图所示。

图片

Icecream同时打印表达式和它的值

用 IceCream Debug 也可以应用于普通的 Python 数据结构。下面是一个Python字典的例子。

sample_dict = {1:"A", 2:"B", 3:"C"}
ic(sample_dict[1])
ic| sample_dict[1]: 'A'

检查执行情况

很多时候,程序员使用print()来显示有意义的(有时是随机的)语句来确定程序的流程。

def func(input_num):
if input_num == 1:
print("If Executed!")
...
else:
print("Else Executed!")
...

IceCream也可以避免那些奇怪的声明。

## icecream_demo.py
from icecream import ic
def func(input_num):
if input_num == 1:
ic()
...
else:
ic()
...
func(2)

只要调用ic()就可以了。它将打印文件名、行号和其他细节(如函数名,如果有的话)以及时间。这样看,是不是非常简单。

使用IceCream项目范围

接下来,你可能会想,print() 函数是Python 的内置库,使用方便,不需每次都import。而我们的IceCream 是否需要在每个Python文件中都导入这个库?当然不是!

为了使方法在所有项目文件中可用,在根文件中导入icecream的install模块,如下所示。

## main_file.py
from icecream import install
install()
from help_file import func
func(2)

## help_file.py
def func(num):
ic(num)
return 2*num

通过install,ic()可以在整个项目中使用。

添加一个自定义前缀

如果你注意到上面,ic()​语句的输出以"ic|"开始。那是IceCream提供的默认前缀。

然而,如果由于某种原因,你希望用一个自定义的前缀来代替它,我们可以通过在 ic.configureOutput()​ 方法中指定 prefix 参数来实现的,如下所示。

from icecream import ic
ic.configureOutput(prefix='ic debug| -> ')
ic("A custom prefix")

调试后删除IceCream语句

一旦你的代码调试结束,你可能想删除所有不必要的调试语句。

由于ic()​语句在语法上与print()​不同,你可以在编辑器中搜索"ic("模式并删除这些语句,如下所示。

图片

从代码中删除ic()语句

另外,你可以使用ic.disable()​来停止ic()​的打印。如果你想再次使用它们,请使用ic.enable()。

写在最后

用print()语句进行调试是一种混乱的、不优雅的方法。将输出映射到其相应的调试语句是很混乱的。此外,它需要额外的手动格式化来理解输出。

如上所述,Python 中的 IceCream 库是一个很好的替代品。它使调试不费吹灰之力,可读性强,代码最少。如果你觉得本文对你有所帮助,可以点个赞和在看!

图片

参考资料:

[1]IceCream: https://github.com/gruns/icecream

责任编辑:武晓燕 来源: 数据STUDIO
相关推荐

2021-08-13 14:08:24

Windows 11Windows微软

2023-03-16 19:17:57

2009-10-15 08:52:42

Windows 7销售市场

2018-08-24 06:13:18

IPv6SDNIPv4

2021-04-19 11:45:31

Pythonswitch编程语言

2021-04-16 15:02:38

Python 开发编程语言

2021-11-17 10:18:31

iOS苹果系统

2022-02-13 00:03:06

AndroidAndroid 13安卓

2012-07-16 14:32:44

2020-04-13 17:17:28

MySQL8.0功能

2010-08-06 12:01:46

RIP协议IPv6

2020-02-11 13:05:42

Wi-Fi 65GWi-Fi

2022-05-31 16:08:25

Web3算法挑战

2013-02-25 10:33:52

Windows 8Windows Blu

2011-06-03 09:33:01

Windows 8

2013-07-17 10:07:29

Windows Pho功能

2017-03-13 08:40:45

AndroidDebugBuildConfig

2012-03-12 10:31:17

XeonE5-2600

2023-07-26 19:22:04

WiFi 7WiFi 6

2019-01-10 14:21:12

iOS功能苹果
点赞
收藏

51CTO技术栈公众号