日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python 错误、调试、单元测试、文档测试

發(fā)布時間:2025/3/20 python 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 错误、调试、单元测试、文档测试 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

錯誤分為程序的錯誤和由用戶錯誤的輸入引起的錯誤,此外還有因為各種各樣意外的情況導(dǎo)致的錯誤,比如在磁盤滿的時候?qū)懭搿木W(wǎng)絡(luò)爬取東西的時候,網(wǎng)絡(luò)斷了。這類錯誤稱為異常

錯誤處理
  
普通的錯誤處理機制就是在出錯的時候返回一個錯誤代碼,但是這樣十分不方便,一是因為錯誤碼是和正常結(jié)果一樣的方式返回的,判斷起來十分不方便,二是錯誤還需要一級一級的向上報,直到錯誤處理程序。

所以高級語言通常都內(nèi)置了一套 try…except…finally… 的錯誤處理機制,Python也不例外。

try:A#如果A中的代碼執(zhí)行過程中出錯,就會執(zhí)行B中的代碼 except ZeroDivisionError as e:B finally:C#C中的代碼無論是否出錯都會正常執(zhí)行(可以不要這個)<br>。。。

如果錯誤有不同的類型,可以說使用多個except語句,每個語句處理一個類型的錯誤

另外,可以在except后面加一個else,如果沒有出錯,會執(zhí)行else

Python 的錯誤其實也是一個類,所有的異常類型都是從BaseException類派生的

except在捕獲錯誤時,不但捕獲該類型的錯誤,而且還會把子類一網(wǎng)打盡

''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' try:foo() except ValueError as e:print('ValueError') except UnicodeError as e:print('UnicodeError') #第二個except永遠也捕獲不到UnicodeError,因為UnicodeError是ValueError的子類,如果有,也被第一個except給捕獲了。

使用try…except還有一個巨大的好處,就是可以跨越多層調(diào)用,比如函數(shù)main()調(diào)用foo(),foo()調(diào)用bar(),結(jié)果bar()出錯了,這時,只要main()捕獲到了,就可以處理。也就是說,不需要在每個可能出錯的地方去捕獲錯誤,只要在合適的層次去捕獲錯誤就可以了。這樣一來,就大大減少了寫try…except…finally的麻煩。

記錄錯誤
如果不捕獲錯誤,自然可以讓Python解釋器來打印出錯誤堆棧,但程序也被結(jié)束了。既然我們能捕獲錯誤,就可以把錯誤堆棧打印出來,然后分析錯誤原因,同時,讓程序繼續(xù)執(zhí)行下去。

Python內(nèi)置的logging模塊可以非常容易地記錄錯誤信息

通過配置,logging還可以把錯誤記錄到日志文件里,方便事后排查。

拋出錯誤
因為錯誤是class,捕獲一個錯誤就是捕獲到該class的一個實例。因此,錯誤并不是憑空產(chǎn)生的,而是有意創(chuàng)建并拋出的。Python的內(nèi)置函數(shù)會拋出很多類型的錯誤,我們自己編寫的函數(shù)也可以拋出錯誤。

如果要拋出錯誤,首先根據(jù)需要,可以定義一個錯誤的class,選擇好繼承關(guān)系,然后,用raise語句拋出一個錯誤的實例

只有在有必要的時候才定義我們自己的錯誤

另外一種錯誤處理
在try…excep捕獲到異常后,還可以在except中使用 ’raise‘把異常拋出去,以便于上級處理,如果raise語句不帶參數(shù),就會把異常原樣拋出去,我們還可以通過raise 跟一個別的異常類型來將一種錯誤的類型轉(zhuǎn)化為另外一種類型如:

try:10 / 0 except ZeroDivisionError:raise ValueError('input error!')

這種類型應(yīng)該是一種合理的類型,而不應(yīng)該將一種類型轉(zhuǎn)化為另外一種不相干的類型

程序也可以主動拋出錯誤,讓調(diào)用者來處理相應(yīng)的錯誤。但是,應(yīng)該在文檔中寫清楚可能會拋出哪些錯誤,以及錯誤產(chǎn)生的原因。

調(diào)試

斷言
我們有事再調(diào)試的時候為了省事,就直接由print打印出變量的值,斷言的作用和上面一樣,凡是可以用print來輔助查看的地方,都可以用斷言替代

斷言可以加提示信息,

''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' def foo(s):n = int(s)assert n != 0, 'n is zero!'#檢查n是否是0,返回boolreturn 10 / ndef main():foo('0')

如果斷言失敗,assert語句本身就會拋出AssertionError:提示信息

啟動Python解釋器時可以用-O參數(shù)來關(guān)閉assert:

$ python -O err.py

logging

使用pdb方式來調(diào)試

python -m pdb fortest.py#使用-m pdb 來啟動調(diào)試 l #使用l來查看代碼 n #使用n來執(zhí)行一行代碼 p 變量名#任何時候都可以輸入p加變量名來查看變量 q#使用q退出

pdb.set_trace()
這個方法也是用pdb,但是不需要單步執(zhí)行,我們只需要import pdb,然后,在可能出錯的地方放一個pdb.set_trace(),就可以設(shè)置一個斷點:

運行代碼,程序會自動在pdb.set_trace()暫停并進入pdb調(diào)試環(huán)境,可以用命令p查看變量,或者用命令c繼續(xù)運行:

IDE

雖然用IDE調(diào)試起來比較方便,但是最后你會發(fā)現(xiàn),logging才是終極武器。

單元測試

為什么編寫單元測試呢,因為在寫好的程序可能在以后還需要修改,這時如果由單元測試,我們就能夠保證修改后的程序在功能上和以前的相同,這一定程度上也減少了測試的繁雜性

這種以測試為驅(qū)動的開發(fā)模式最大的好處就是確保一個程序模塊的行為符合我們設(shè)計的測試用例。在將來修改的時候,可以極大程度地保證該模塊行為仍然是正確的。

接下來,作者舉了一個例子來介紹了單元測試的編寫模式,并且介紹了一些用到的函數(shù)

我們需要引入Python自帶的測試模塊unittest模塊

import unittest

編寫單元測試的時候,需要編寫一個測試類,這個類從unittest.TestCase派生

def TestDict(unittest.TestCase):def test_init(self):pass

以test開頭的方法就是測試方法,不以test開頭的方法就不被認為是測試方法,運行單元測試的時候不會被執(zhí)行

對每一類測試都需要編寫一個測試方法,由于unittest.TestCase內(nèi)置了很多判斷,我們只需要斷言這些輸出是否是我們所需要的,最常用的斷言就是assertEqual(),

self.assertEqual(abs(-1), 1) # 斷言函數(shù)返回的結(jié)果與1相等

另一種重要的斷言就是期待拋出指定類型的Error,比如通過d[‘empty’]訪問不存在的key時,斷言會拋出KeyError:

with self.assertRaises(KeyError):value = d['empty']

運行單元測試

兩種方法,一種直接在模塊中加入

if __name__ == '__main__':unittest.main()

另一種方法是在命令行通過參數(shù)-m unittest直接運行單元測試

這是推薦的做法,因為這樣可以一次批量運行很多單元測試,并且,有很多工具可以自動來運行這些單元測試。

setUp和tearDown

這兩個函數(shù)可以寫在測試類中,作用就是再每個測試方法被調(diào)用之前會執(zhí)行setUp(),被調(diào)用之后會執(zhí)行tearDown(),可以把一些準(zhǔn)備工作、和善后工作放到這些函數(shù)中。

  • 單元測試可以有效地測試某個程序模塊的行為,是未來重構(gòu)代碼的信心保證。

  • 單元測試的測試用例要覆蓋常用的輸入組合、邊界條件和異常。

  • 單元測試代碼要非常簡單,如果測試代碼太復(fù)雜,那么測試代碼本身就可能有bug。

  • 單元測試通過了并不意味著程序就沒有bug了,但是不通過程序肯定有bug。

文檔測試

文檔測試就是運行寫在注釋中的實例代碼

文檔測試不能再調(diào)試(Debugger)模式下運行,否則會報錯

PYDEV DEBUGGER WARNING: sys.settrace() should not be used when the debugger is being used. This may cause the debugger to stop working correctly. If this is needed, please check: http://pydev.blogspot.com/2007/06/why-cant-pydev-debugger-work-with.html to see how to restore the debug tracing back correctly. Call Location:File "c:\users\administrator.sc-201605202132\appdata\local\programs\python\python36\Lib\doctest.py", line 1480, in runsys.settrace(save_trace)

很多文檔都有示例代碼,可以把這些示例代碼在Python的交互環(huán)境下運行。這些代碼與其他說明可以寫在注釋中,然后,由一些工具來自動生成文檔

''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' def abs(n):'''Function to get absolute value of number.Example:>>> abs(1)1>>> abs(-1)1>>> abs(0)0'''return n if n >= 0 else (-n)

無疑更明確地告訴函數(shù)的調(diào)用者該函數(shù)的期望輸入和輸出。并且,Python內(nèi)置的“文檔測試”(doctest)模塊可以直接提取注釋中的代碼并執(zhí)行測試。

doctest嚴格按照Python交互式命令行的輸入和輸出來判斷測試結(jié)果是否正確。只有測試異常的時候(即真正運行的結(jié)果和實例代碼中的結(jié)果不一樣的時候,就會報錯),可以用…表示中間一大段煩人的輸出。

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的python 错误、调试、单元测试、文档测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。