3个可视化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

是否希望输出能更容易理解,如下图所示?

是否想可视化正在执行哪些代码以及它们实时执行了多少次?

本文将介绍三个工具,来实现上面的操作:

  • Loguru —更好地打印异常

  • snoop — 打印函数中正在执行的代码行

  • heartrate — 实时可视化 Python 程序的执行过程

最为方便地是,使用这些工具只需要一行代码!

Logure—更好地打印异常

Loguru是一个旨在使Python日志变得有趣的库。Loguru提供了许多有趣的功能,但是我发现最有用的功能是能够捕获意外错误,并显示变量的哪个值导致您的代码失败。

安装loguru

pip install loguru

为了理解loguru的有效性,假设你有两个函数 division 和 divide_numbers ,然后执行了 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)

在运行上面的代码之后,我们得到了这个错误:

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

从输出中,我们可以知道是 return num1/num2 这一行出现了错误,但是我们不知道 num1 和 num2 的哪个值导致了错误。幸运的是,可以通过添加 Loguru 的 logger.catch 装饰器来轻松跟踪:

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 包,它通过只添加一个装饰器来打印正在执行的代码行以及每个变量的值。

安装 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(5) 的输出为什么是20,我们可以在函数 factorial 中添加 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)}")

输出:

在上面的输出中,我们可以查看变量的值以及执行的代码行。现在我们可以更好地理解递归是如何工作的了!

heartrate — 实时可视化 Python 程序的执行过程

如果你想要可视化哪些行被执行以及执行了多少次,请尝试 heartrate。

安装 heartrate :

pip install heartrate

现在我们将 heartrate.trace (browser = True)添加到前面的代码中。这将打开一个浏览器窗口,显示调用 trace()的文件的可视化信息。

import heartrate 
heartrate.trace(browser=True)


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)}")

当你运行上面的代码时,应该会弹出一个新的浏览窗口。如果没有,就去 http://localhost:9999。你应该看到如下输出:

太酷了!

从上面的输出,我们可以看到程序执行:

  • if x==1 5次

  • return 1 1次

  • return (x * factorial(x-1)) 4次

现在让我们看看使用 heartrate 实时可视化 Python 程序的执行是什么样的。让我们添加 sleep(0.5) ,这样程序运行得稍微慢一点,并将 num 增加到20。

import heartrate 
from time import sleep


heartrate.trace(browser=True)




def factorial(x):
    if x == 1:
        return 1
    else:
        sleep(0.5)
        return (x * factorial(x-1))




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

哇,太酷了!我们可以看到正在执行哪些代码行,以及每行代码实时执行了多少次。

总结

本文我们学习了3个工具来跟踪和可视化 Python 代码的执行情况。使用这三个工具可以让我们的调试工作不再那么痛苦,只需要一行代码,为什么不试试看他们有多大用处呢?

·  END  ·

HAPPY LIFE

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值