python中debug有什么用途_史上最方便的Python Debug工具
最近在github上冒出了一個python的debug神器PySnooper,號稱在debug時可以消滅print。那么該工具有哪些優點呢,如何使用該工具呢。本文就介紹該工具的優缺點和使用方式。
前言
使用python開發過程中,總是避免不了debug。傳統的debug過程大致分為兩種:
a)斷點+單步調試。
斷點+單步調試估計是用的最多的了,對于較大型項目來說,其流程大致為:先在關鍵的代碼位置加上print語句,通過分析print的值將范圍縮小,這個過程可能需要重復多次,使用print的方法,一般可以將范圍縮小到一個比較完整的功能模塊中;然后在可能出現bug的模塊中的關鍵部分打上斷點,進入到斷點后使用單步調試,查看各變量的值是否正確,最后根據錯誤的變量值定位到具體的代碼行,最后進行修改。
b) pdb調試。
pdb是python自帶的一個包,為 python 程序提供了一種交互的源代碼調試功能,主要特性包括設置斷點、單步調試、進入函數調試、查看當前代碼、查看棧片段、動態改變變量的值等。pdb的調試流程和1)基本差不多,其具體的使用方法大家可以網上搜一下。
傳統的debug的方法的缺點包括:
a)需要在代碼中添加print語句,這就改變了原有的代碼;
b)在斷點調試和單步調試過程中,需要保持持續的專注,一旦跳過了關鍵點就要從頭開始。
最近在github上冒出了一個debug工具,可以解決傳統debug過程中的缺點。下面一塊來看看這個工具的使用和神奇之處。
Python學習交流群:835017344,這里是python學習者聚集地,有大牛答疑,有資源共享!有想學習python編程的,或是轉行,或是大學生,還有工作中想提升自己能力的,正在學習的小伙伴歡迎加入學習。
1. PySnooper是什么
image
該工具使用采用裝飾器的形式,將函數的運行過程以日志的形式打印到文件中,其記錄了運行了哪些代碼行,運行的時間及運行到當前代碼時各變量的值。根據變量的變化就可以定位問題了。親自試用該工具后,其優點可總結為以下幾點:
1、無需為了查看變量的值,使用print打印變量的值,從而修改了原有的代碼。
2、接口的運行過程以日志的形式保存,方便隨時查看。
3、可以根據需要,設置函數調用的函數的層數,方便將注意力集中在需要重點關注的代碼段。
4、多個函數的日志,可以設置日志前綴表示進行標識,方便查看時過濾。
該工具有這么多優點,那么如何使用呢,下面結合demo來介紹該工具的使用。
2. 使用方式介紹
2.1 工具安裝
pip install pysnooper
2.2官方demo介紹
官方demo代碼:
import pysnooper
@pysnooper.snoop()
def number_to_bits(number):
if number:
bits = []
while number:
number, remainder = divmod(number, 2)
bits.insert(0, remainder)
return bits
else:
return [0]
number_to_bits(6)
控制臺輸出:
image
控制臺的輸出如上圖,從圖中可以看到,從進入到函數開始,會記錄每一行代碼的執行及記錄新增局部變量或已有局部變量的變化,直到函數結束。以裝飾器的形式使用該工具后,會將函數運行的中間結果打印出來,這樣方便后續的bug定位和分析。
2.3 參數介紹
以裝飾器的形式使用該工具,其包含了四個參數,參數包括output, variables, depth, prefix,如下圖。
image
1、output參數。該參數指定函數運行過程中產生的中間結果的保存位置,若該值為空,則將中間結果輸出到控制臺。
2、variables參數。該參數是vector類型, 因為在默認情況下,裝飾器只跟蹤局部變量,要跟蹤非局部變量,則可以通過該字段來指定。默認值為空vector。
3、depth參數。該參數表示需要追蹤的函數調用的深度。在很多時候,我們在函數中會調用其他函數,通過該參數就可以指定跟蹤調用函數的深度。默認值為1。
4、prefix參數。該參數用于指定該函數接口的中間結果前綴。當多個函數都使用的該裝飾器后,會將這些函數調用的中間結果保存到一個文件中,此時就可以通過前綴過濾不同函數調用的中間結果。默認值為空字符串。
3. 工具應用
要使用該工具只需要理解該裝飾器(snoop)的參數的含義,下面結合幾個demo介紹參數的使用及對結果的影響。
3.1 output 參數使用
若使用默認參數,則將中間結果輸出到控制臺,若填寫該參數,則將中間結果寫入到該參數指定的目錄下,如運行以下代碼,其中間結果會保存在裝飾器snoop中設置日志保存的路徑中,注意這里不會自動創建目錄,所以需要事先創建目錄,如測試代碼中填寫路徑后需要創建log目錄。
測試代碼:
import pysnooper
def add(num1, num2):
return num1 + num2
@pysnooper.snoop("./log/debug.log", prefix="--*--")
def multiplication(num1, num2):
sum_value = 0
for i in range(0, num1):
sum_value = add(sum_value, num2)
return sum_value
value = multiplication(3, 4)
運行該代碼后,在./log/debug.log的內容如下:
image
從運行代碼的中間結果中可以看出,文件中記錄了各行代碼的執行過程及局部變量的變化。在debug時,通過分析該文件,就可以跟蹤每一步的執行過程及局部變量的變化,這樣就能快速的定位問題所在;由于運行的中間結果保存在文件中,方便隨時分析其運行的中間結果,也便于共享。
3.2 variables參數使用
在默認參數的情況下,使用該工具只能查看局變量的變化過程,當需要查看局部變量以外變量時,則可以通過variables參數進行設置,比如下方代碼,在Foo類型,需要查看類實例的變量self.num1, self.num2, self.sum_value,則可以看將該變量設置當參數傳入snoop的裝飾器中。
測試代碼:
import pysnooper
class Foo(object):
def __init__(self):
self.num1 = 0
self.num2 = 0
self.sum_value = 0
def add(self, num1, num2):
return num1 + num2
@pysnooper.snoop(output="./log/debug.log", variables=("self.num1", "self.num2", "self.sum_value"))
def multiplication(self, num1, num2):
self.num1 = num1
self.num2 = num2
sum_value = 0
for i in range(0, num1):
sum_value = self.add(sum_value, num2)
self.sum_value = sum_value
return sum_value
foo = Foo()
foo.multiplication(3, 4)
為了體現該參數的作用,這里分別使用默認參數和上述參數(代碼中設置的參數)運行代碼,得到的結果如下:
image
使用默認參數的結果image
使用代碼中參數的結果從兩個中間結果中可以看出,若變量不是局部變量,哪怕在函數中使用了該變量,如果不顯示設置打印該變量的中間結果,則不會將該變量的中間結果打印到文件中。
3.3 depth參數使用
該參數用來指定記錄函數調用層數的結果,默認值為1,若要查看多層函數調用的中間結果,則可將該參數設置為>=2。
測試代碼:
import pysnooper
def add(num1, num2):
return num1 + num2
@pysnooper.snoop("./log/debug.log", depth=2)
def multiplication(num1, num2):
sum_value = 0
for i in range(0, num1):
sum_value = add(sum_value, num2)
return sum_value
value = multiplication(3, 4)
為了對比,將depth的值分別設置為1和2,其結果如下:
image
depth=1的結果image
depth=2的結果從上述結果中可以看出,若要查看更深層次函數調用的情況,則可以通過設置depth值進行查看。這樣方便用戶有選擇性的查看函數的調用情況。
3.4 prefix參數使用
該參數主要用于設置中間結果的前綴,這樣就可以區分不同的函數調用的中間結果,默認參數為""。
測試代碼:
import pysnooper
def add(num1, num2):
return num1 + num2
@pysnooper.snoop("./log/debug.log", prefix="--*--")
def multiplication(num1, num2):
sum_value = 0
for i in range(0, num1):
sum_value = add(sum_value, num2)
return sum_value
value = multiplication(3, 4)
運行代碼后的中間結果如下:
image
從結果中可以看到,中間結果的每一行都包含了prefix設置的前綴,這樣便于區分不同的函數調用的中間結果。
上述的介紹為了將注意力集中到具體的參數,采取設置單一參數的形式進行介紹(output+其他單個參數)。在實際使用時,可以同時設置多個參數。使用PySnooper工具來記錄函數運行的中間結果,比起傳統的使用斷點+單步調試,pdb等調試方法,PySnooper工具有著巨大的優勢。
4. 該工具的不足之處
雖然使用debug在使用PySnooper很方便,但還是存在一些問題(以4月26號拉取代碼為依據),比如:
1、無法很好的支持遞歸調用。
2、調用每個函數的中間結果只能保存在一個文件中,如果需要區分不同文件的結果,需要使用prefix來進行前綴標識。
3、對于跨文件函數調用,不支持記錄調用函數所在的文件名。
當然PySnooper是最近在github上火起來的項目,還不夠完善是正常的,相信這些不足之處后續也會得到完善,期待一個更好的PySnooper。
5. 總結
本文介紹PpySnooper的工具,先介紹了該工具是什么,相比傳統debug方法的優勢,然后介紹了該工具的參數及說明該參數作用的demo。最后介紹了該工具的不足之處。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的python中debug有什么用途_史上最方便的Python Debug工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 插件视频倍速快捷键(插件视频倍速快捷键设
- 下一篇: 蒋干是一个怎样的人(人物蒋干的性格特点是