<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          別再用print輸出來調(diào)試代碼了

          共 5332字,需瀏覽 11分鐘

           ·

          2021-07-28 00:07


          點擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

          重磅干貨,第一時間送達(dá)

          本文轉(zhuǎn)自|機(jī)器學(xué)習(xí)算法那些事

          | 導(dǎo)語 最近在github上冒出了一個python的debug神器PySnooper,號稱在debug時可以消滅print。那么該工具有哪些優(yōu)點呢,如何使用該工具呢。本文就介紹該工具的優(yōu)缺點和使用方式。


          前言:











          使用python開發(fā)過程中,總是避免不了debug。傳統(tǒng)的debug過程大致分為兩種:


          a)斷點+單步調(diào)試。

          斷點+單步調(diào)試估計是用的最多的了,對于較大型項目來說,其流程大致為:先在關(guān)鍵的代碼位置加上print語句,通過分析print的值將范圍縮小,這個過程可能需要重復(fù)多次,使用print的方法,一般可以將范圍縮小到一個比較完整的功能模塊中;然后在可能出現(xiàn)bug的模塊中的關(guān)鍵部分打上斷點,進(jìn)入到斷點后使用單步調(diào)試,查看各變量的值是否正確,最后根據(jù)錯誤的變量值定位到具體的代碼行,最后進(jìn)行修改。


          b) pdb調(diào)試。

          pdb是python自帶的一個包,為 python 程序提供了一種交互的源代碼調(diào)試功能,主要特性包括設(shè)置斷點、單步調(diào)試、進(jìn)入函數(shù)調(diào)試、查看當(dāng)前代碼、查看棧片段、動態(tài)改變變量的值等。pdb的調(diào)試流程和1)基本差不多,其具體的使用方法大家可以網(wǎng)上搜一下。


          傳統(tǒng)的debug的方法的缺點包括:

          a)需要在代碼中添加print語句,這就改變了原有的代碼; 

          b)在斷點調(diào)試和單步調(diào)試過程中,需要保持持續(xù)的專注,一旦跳過了關(guān)鍵點就要從頭開始。


          最近在github上冒出了一個debug工具,可以解決傳統(tǒng)debug過程中的缺點。下面一塊來看看這個工具的使用和神奇之處。


          1. PySnooper是什么














          該工具使用采用裝飾器的形式,將函數(shù)的運行過程以日志的形式打印到文件中,其記錄了運行了哪些代碼行,運行的時間及運行到當(dāng)前代碼時各變量的值。根據(jù)變量的變化就可以定位問題了。親自試用該工具后,其優(yōu)點可總結(jié)為以下幾點:


          1、無需為了查看變量的值,使用print打印變量的值,從而修改了原有的代碼。


          2、接口的運行過程以日志的形式保存,方便隨時查看。


          3、可以根據(jù)需要,設(shè)置函數(shù)調(diào)用的函數(shù)的層數(shù),方便將注意力集中在需要重點關(guān)注的代碼段。


          4、多個函數(shù)的日志,可以設(shè)置日志前綴表示進(jìn)行標(biāo)識,方便查看時過濾。


          該工具有這么多優(yōu)點,那么如何使用呢,下面結(jié)合demo來介紹該工具的使用。


          2. 使用方式介紹












          1. 工具安裝

          pip install pysnooper


          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)


           控制臺輸出:

          控制臺的輸出如上圖,從圖中可以看到,從進(jìn)入到函數(shù)開始,會記錄每一行代碼的執(zhí)行及記錄新增局部變量或已有局部變量的變化,直到函數(shù)結(jié)束。以裝飾器的形式使用該工具后,會將函數(shù)運行的中間結(jié)果打印出來,這樣方便后續(xù)的bug定位和分析。


          3. 參數(shù)介紹

          以裝飾器的形式使用該工具,其包含了四個參數(shù),參數(shù)包括output, variables, depth, prefix,如下圖。


          1、output參數(shù)。該參數(shù)指定函數(shù)運行過程中產(chǎn)生的中間結(jié)果的保存位置,若該值為空,則將中間結(jié)果輸出到控制臺。


          2、variables參數(shù)。該參數(shù)是vector類型, 因為在默認(rèn)情況下,裝飾器只跟蹤局部變量,要跟蹤非局部變量,則可以通過該字段來指定。默認(rèn)值為空vector。


          3、depth參數(shù)。該參數(shù)表示需要追蹤的函數(shù)調(diào)用的深度。在很多時候,我們在函數(shù)中會調(diào)用其他函數(shù),通過該參數(shù)就可以指定跟蹤調(diào)用函數(shù)的深度。默認(rèn)值為1。


          4、prefix參數(shù)。該參數(shù)用于指定該函數(shù)接口的中間結(jié)果前綴。當(dāng)多個函數(shù)都使用的該裝飾器后,會將這些函數(shù)調(diào)用的中間結(jié)果保存到一個文件中,此時就可以通過前綴過濾不同函數(shù)調(diào)用的中間結(jié)果。默認(rèn)值為空字符串。


          3. 工具應(yīng)用












          要使用該工具只需要理解該裝飾器(snoop)的參數(shù)的含義,下面結(jié)合幾個demo介紹參數(shù)的使用及對結(jié)果的影響。


          1. output 參數(shù)使用

          若使用默認(rèn)參數(shù),則將中間結(jié)果輸出到控制臺,若填寫該參數(shù),則將中間結(jié)果寫入到該參數(shù)指定的目錄下,如運行以下代碼,其中間結(jié)果會保存在裝飾器snoop中設(shè)置日志保存的路徑中,注意這里不會自動創(chuàng)建目錄,所以需要事先創(chuàng)建目錄,如測試代碼中填寫路徑后需要創(chuàng)建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的內(nèi)容如下:


          從運行代碼的中間結(jié)果中可以看出,文件中記錄了各行代碼的執(zhí)行過程及局部變量的變化。在debug時,通過分析該文件,就可以跟蹤每一步的執(zhí)行過程及局部變量的變化,這樣就能快速的定位問題所在;由于運行的中間結(jié)果保存在文件中,方便隨時分析其運行的中間結(jié)果,也便于共享。


          2. variables參數(shù)使用

          在默認(rèn)參數(shù)的情況下,使用該工具只能查看局變量的變化過程,當(dāng)需要查看局部變量以外變量時,則可以通過variables參數(shù)進(jìn)行設(shè)置,比如下方代碼,在Foo類型,需要查看類實例的變量self.num1, self.num2, self.sum_value,則可以看將該變量設(shè)置當(dāng)參數(shù)傳入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)


          為了體現(xiàn)該參數(shù)的作用,這里分別使用默認(rèn)參數(shù)和上述參數(shù)(代碼中設(shè)置的參數(shù))運行代碼,得到的結(jié)果如下:

          使用默認(rèn)參數(shù)的結(jié)果


          使用代碼中參數(shù)的結(jié)果


          從兩個中間結(jié)果中可以看出,若變量不是局部變量,哪怕在函數(shù)中使用了該變量,如果不顯示設(shè)置打印該變量的中間結(jié)果,則不會將該變量的中間結(jié)果打印到文件中。


          3. depth參數(shù)使用

          該參數(shù)用來指定記錄函數(shù)調(diào)用層數(shù)的結(jié)果,默認(rèn)值為1,若要查看多層函數(shù)調(diào)用的中間結(jié)果,則可將該參數(shù)設(shè)置為>=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的值分別設(shè)置為1和2,其結(jié)果如下:

          depth=1的結(jié)果


          depth=2的結(jié)果


          從上述結(jié)果中可以看出,若要查看更深層次函數(shù)調(diào)用的情況,則可以通過設(shè)置depth值進(jìn)行查看。這樣方便用戶有選擇性的查看函數(shù)的調(diào)用情況。


          4. prefix參數(shù)使用

          該參數(shù)主要用于設(shè)置中間結(jié)果的前綴,這樣就可以區(qū)分不同的函數(shù)調(diào)用的中間結(jié)果,默認(rèn)參數(shù)為""。


          測試代碼:

          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)


          運行代碼后的中間結(jié)果如下:


          從結(jié)果中可以看到,中間結(jié)果的每一行都包含了prefix設(shè)置的前綴,這樣便于區(qū)分不同的函數(shù)調(diào)用的中間結(jié)果。

          上述的介紹為了將注意力集中到具體的參數(shù),采取設(shè)置單一參數(shù)的形式進(jìn)行介紹(output+其他單個參數(shù))。在實際使用時,可以同時設(shè)置多個參數(shù)。使用PySnooper工具來記錄函數(shù)運行的中間結(jié)果,比起傳統(tǒng)的使用斷點+單步調(diào)試,pdb等調(diào)試方法,PySnooper工具有著巨大的優(yōu)勢。


          4. 該工具的不足之處












          雖然使用debug在使用PySnooper很方便,但還是存在一些問題(以4月26號拉取代碼為依據(jù)),比如:


          1、無法很好的支持遞歸調(diào)用。


          2、調(diào)用每個函數(shù)的中間結(jié)果只能保存在一個文件中,如果需要區(qū)分不同文件的結(jié)果,需要使用prefix來進(jìn)行前綴標(biāo)識。


          3、對于跨文件函數(shù)調(diào)用,不支持記錄調(diào)用函數(shù)所在的文件名。


          當(dāng)然PySnooper是最近在github上火起來的項目,還不夠完善是正常的,相信這些不足之處后續(xù)也會得到完善,期待一個更好的PySnooper。


          5. 總結(jié)












          本文介紹PpySnooper的工具,先介紹了該工具是什么,相比傳統(tǒng)debug方法的優(yōu)勢,然后介紹了該工具的參數(shù)及說明該參數(shù)作用的demo。最后介紹了該工具的不足之處。



          下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
          在「小白學(xué)視覺」公眾號后臺回復(fù):擴(kuò)展模塊中文教程即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

          下載2:Python視覺實戰(zhàn)項目52講
          小白學(xué)視覺公眾號后臺回復(fù):Python視覺實戰(zhàn)項目即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學(xué)校計算機(jī)視覺。

          下載3:OpenCV實戰(zhàn)項目20講
          小白學(xué)視覺公眾號后臺回復(fù):OpenCV實戰(zhàn)項目20講即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

          交流群


          歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~


          瀏覽 32
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  手机看片久久 | 99热网站 | 久久无人区无码 | 一区二区欧美精品 | 超碰香蕉|