编程五年,这两款 Python 代码调试工具真的很棒

大家好,今天我给大家分享两款便于调试 Python 代码的工具,它们可以方便展示我们调试代码的中间状态,提升大家的编码效率。

闲话少说,我们直接开始吧。。。

在日常工作中,写 Python 的小伙伴经常会遇调试代码 bug 的情形,有时候我们 Python 的错误提示信息特别丑,举例如下:

2 divided by 1 is equal to 2.0.
Traceback (most recent call last):
  File "loguru_example.py", line 17, in <module>
    divide_numbers(num_list)
  File "loguru_example.py", line 11, in divide_numbers
    res = division(num1, num2)
  File "loguru_example.py", line 5, in division
    return num1/num2
ZeroDivisionError: division by zero

如果你觉得尚可接受,那我们不妨来看下如下显示错误的方式:

看了上述的显示,有木有心动。

是的,我们可以通过一些Python的第三方包,来实现上述调试效果。我们来看如下两款第三方Python包:

  • Loguru: 更好的打印程序异常
  • snoop: 打印函数中正在执行的代码行

好了,接下来我们就来一个个的介绍这些好用的工具吧。

Loguru

Loguru是一个旨在使Python中的日志显示变得有趣的库。Loguru提供了许多有趣的功能,但我发现该库最有用的一个功能是捕获程序异常并显示导致代码失败的变量值。

安装

我们可以使用pip来直接进行安装,代码如下:

pip install loguru

举个栗子

为了理解Loguru是如何工作的,假设我们现在有两个函数_division_和_divide_numbers_,如下所示:

from itertools import combinations

def division(num1: int, num2: int):
    return num1/num2

def divide_numbers(num_list: list):
  """Division of 2 numbers in the number list """
  
    for comb in combinations(num_list, 2):
        num1, num2 = comb 
        res = division(num1, num2)
        print(f"{num1} divided by {num2} is equal to {res}.")

if __name__ =='__main__':
    num_list = [2, 1, 0]
    divide_numbers(num_list)

注意_combinations([2,1,0], 2)返回值为[(2, 1), (2, 0), (1, 0)]_。运行上述代码后,我们会出现以下错误:

2 divided by 1 is equal to 2.0.
Traceback (most recent call last):
  File "loguru_example.py", line 17, in <module>
    divide_numbers(num_list)
  File "loguru_example.py", line 11, in divide_numbers
    res = division(num1, num2)
  File "loguru_example.py", line 5, in division
    return num1/num2
ZeroDivisionError: division by zero

使用Loguru

通过上述输出,我们知道代码行 return num1/num2 是错误发生的地方,但是我们并不清楚num1和num2的那些值导致的错误。幸运的是,我们可以通过添加Loguru的装饰器来捕捉此时的异常,代码如下:

from loguru import logger 
from itertools import combinations

def division(num1: int, num2: int):
    return num1/num2

@logger.catch # Add this to track errors
def divide_numbers(num_list: list):
    for comb in combinations(num_list, 2):
        num1, num2 = comb 
        res = division(num1, num2)
        print(f"{num1} divided by {num2} is equal to {res}.")

if __name__ =='__main__':
    num_list = [2, 1, 0]
    divide_numbers(num_list)

运行结果如下:

通过在代码中添加_logger.catch_,此时的异常情况更加容易被理解!我们通过观察此时的输出,可以明确地知道当2除以0时导致函数出现异常错误信息。

Snoop

如果我们编写完的代码经过调试后没有了错误,但我们想弄清楚代码运行时发生了什么?这就是snoop派上用场的情形。

安装

snoop是一个第三方的Python包,通过只添加一个装饰器可以方便地打印正在执行的代码行以及每个变量的值。

同样我们依然可以通过pip来安装snoop库,代码如下:

pip install snoop

举个栗子

假设我们有一个名为factorial的函数,它主要用于实现计算整数的阶乘。

代码如下:

import snoop 

def factorial(x: int):
    if x == 1:
        return 1
    else:
        return (x * factorial(x-1))
        
if __name__ == "__main__":
    num = 5
    print(f"The factorial of {num} is {factorial(num)}")

輸出如下:

The factorial of 5 is 120

使用 factorial

为了理解为什么函数_factorial_的输出值为20,我们可以通过添加_snoop_的装饰器来查看函数的调用情形,代码如下:

import snoop 

@snoop
def factorial(x):
    if x == 1:
        return 1
    else:
        return (x * factorial(x-1))

if __name__ == "__main__":
    num = 5
    print(f"The factorial of {num} is {factorial(num)}")

输出如下:

在上述输出中,我们可以查看变量的值以及实际代码运行情形。进而通过上述输出,我们可以更好地理解递归的工作原理!

总结

本文重点介绍了两种跟踪和可视化Python代码执行的工具。我希望通过使用这两款调试工具,来大大提升大家的工作效率和定位问题的能力。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值