首頁 > 軟體

分享方便偵錯Python程式碼的2個實用工具

2022-05-24 18:02:19

1. 引言

今天來給小夥伴推薦兩款實用的便於偵錯Python程式碼的工具,可以方便展示我們偵錯程式碼的中間狀態,提升大家的編碼效率。

2. 動機

在日常工作中,經常寫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: 列印函數中正在執行的程式碼行

好了,接下來我們就來一個個的介紹這些好用的工具吧。

3. Loguru

Loguru是一個旨在使Python中的紀錄檔顯示變得有趣的庫。Loguru提供了許多有趣的功能,但我發現該庫最有用的一個功能是捕獲程式異常並顯示導致程式碼失敗的變數值。

3.1 安裝

我們可以使用pip來直接進行安裝,程式碼如下:

pip install loguru

3.2 舉個栗子

為了理解Loguru是如何工作的,假設我們現在有兩個函數divisiondivide_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

3.3 使用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時導致函數出現異常錯誤資訊。

4. Snoop

如果我們編寫完的程式碼經過偵錯後沒有了錯誤,但我們想弄清楚程式碼執行時發生了什麼?這就是snoop派上用場的情形。

4.1 安裝

snoop是一個第三方的Python包,通過只新增一個裝飾器可以方便地列印正在執行的程式碼行以及每個變數的值。
同樣我們依然可以通過pip來安裝snoop庫,程式碼如下:

pip install snoop

4.2 舉例

假設我們有一個名為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

 

4.3 使用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)}")

輸出如下:

在上述輸出中,我們可以檢視變數的值以及實際程式碼執行情形。進而通過上述輸出,我們可以更好地理解遞迴的工作原理!

5. 總結

文章重點介紹了兩種跟蹤和視覺化Python程式碼執行的工具。我希望通過使用這兩款偵錯工具,來大大提升大家的工作效率和定位問題的能力。

到此這篇關於分享方便偵錯Python程式碼的2個實用工具的文章就介紹到這了,更多相關 Python偵錯程式碼工具內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com