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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Day-10: 错误、调试和测试

發布時間:2024/1/17 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Day-10: 错误、调试和测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  程序運行時,會遇到各種各樣的錯誤。

  編寫錯誤叫做bug,而另一類由于運行過程中無法預測的,比如寫文件時,磁盤滿了,寫不進去;或者從網絡抓取數據,網絡突然掉了。這些錯誤稱為異常,程序中需要對異常進行處理,使得程序能夠運行下去。

  • 錯誤處理

  Python中,程序運行錯誤時,如果錯誤沒有捕獲,它會一直往上拋,最后被Python解釋器捕獲,打印一個錯誤。

# err.py: def foo(s):return 10 / int(s)def bar(s):return foo(s) * 2def main():bar('0')main() $ python err.py Traceback (most recent call last):File "err.py", line 11, in <module>main()File "err.py", line 9, in mainbar('0')File "err.py", line 6, in barreturn foo(s) * 2File "err.py", line 3, in fooreturn 10 / int(s) ZeroDivisionError: integer division or modulo by zero

從上到下,錯誤會一層層的反饋,直到顯示最終出錯的地方。

  try...except...finally...:常用這種方法來檢查錯誤并捕捉到,同時進行相應的處理。

try:print 'try...'r = 10 / 0print 'result:', r except ZeroDivisionError, e:print 'except:', e finally:print 'finally...' print 'END' try... except: integer division or modulo by zero finally... END

  注意到,錯誤類型有很多種,它們其實都是從BaseException類派生出來的,常見的錯誤類型和繼承關系有:https://docs.python.org/2/library/exceptions.html#exception-hierarchy

  • 調試

  程序運行一次就成功的概率很小,基本上不超過1%。一般有如下的調試方法:

  第一種,直接在可能出錯的地方print出來,但是后期會一個個刪掉。

  第二種,使用斷言來代替。

# err.py def foo(s):n = int(s)assert n != 0, 'n is zero!'return 10 / ndef main():foo('0')

斷言中,如果“n != 0”是錯的,就拋出AssertionError,并顯示后面的字符串。

  第三種,使用logging。

  logging有debug,info,warning,error等幾個級別,從前到后優先級依次提高,即如果,指定level=WARNING后,debug和info就不起作用了。這樣一樣,就可以輸出不同級別的信息,也不用刪除,最后統一控制輸出哪個級別的信息。

  logging的另一個好處是通過簡單的配置,一條語句可以同時輸出到不同的地方,,比如console和文件。

# err.py import logging
logging.basicConfig(level=logging.INFO)s
= '0' n = int(s) logging.info('n = %d' % n) print 10 / n $ python err.py INFO:root:n = 0 Traceback (most recent call last):File "err.py", line 8, in <module>print 10 / n ZeroDivisionError: integer division or modulo by zero

  第四種調試方式,就是調試器pdb,讓程序以單步方式運行,可以隨時查看運行狀態。

# err.py s = '0' n = int(s) print 10 / n

然后,以參數-m pdb啟動,單步運行

$ python -m pdb err.py > /Users/michael/Github/sicp/err.py(2)<module>() -> s = '0' (Pdb) l1 # err.py2 -> s = '0'3 n = int(s)4 print 10 / n [EOF]

輸入n單步運行下一步

(Pdb) n > /Users/michael/Github/sicp/err.py(3)<module>() -> n = int(s) (Pdb) n > /Users/michael/Github/sicp/err.py(4)<module>() -> print 10 / n

輸入p 變量名來查看變量狀態。

(Pdb) p s '0' (Pdb) p n 0

輸入q結束運行

(Pdb) n ZeroDivisionError: 'integer division or modulo by zero' > /Users/michael/Github/sicp/err.py(4)<module>() -> print 10 / n (Pdb) q

  另外在合適的地方,設置pdb.set_trace(),可以作為斷點。

# err.py import pdbs = '0' n = int(s) pdb.set_trace() # 運行到這里會自動暫停 print 10 / n $ python err.py > /Users/michael/Github/sicp/err.py(7)<module>() -> print 10 / n (Pdb) p n 0 (Pdb) c Traceback (most recent call last):File "err.py", line 7, in <module>print 10 / n ZeroDivisionError: integer division or modulo by zero

到達斷點時,進入pdb調試器。

  最后,還有方便的IDE調試器。

  • 單元測試

  單元測試,顧名思義,就是對一個部分測試,可以是一個模塊、一個函數或者一個類。它的目的是保證該單元能夠實現原先規劃的功能,為之后的整體調試做準備。

  例如,現有模塊mydict.py,對它的要求是實現如下功能:

>>> d = Dict(a=1, b=2) >>> d['a'] 1 >>> d.a 1

mydict.py代碼如下:

class Dict(dict):def __init__(self, **kw):super(Dict, self).__init__(**kw)def __getattr__(self, key):try:return self[key]except KeyError:raise AttributeError(r"'Dict' object has no attribute '%s'" % key)def __setattr__(self, key, value):self[key] = value

編寫的單元測試,需要引入unittest模塊,編寫的mydict_test.py如下:

import unittestfrom mydict import Dictclass TestDict(unittest.TestCase):def test_init(self):  # 測試初始化功能d = Dict(a=1, b='test')self.assertEquals(d.a, 1)self.assertEquals(d.b, 'test')self.assertTrue(isinstance(d, dict))def test_key(self):  # 測試key的功能d = Dict()d['key'] = 'value'self.assertEquals(d.key, 'value')def test_attr(self):  # 測試屬性功能d = Dict()d.key = 'value'self.assertTrue('key' in d)self.assertEquals(d['key'], 'value')def test_keyerror(self):  # 測試key錯誤的功能d = Dict()with self.assertRaises(KeyError):value = d['empty']def test_attrerror(self):  # 測試屬性錯誤的功能d = Dict()with self.assertRaises(AttributeError):value = d.empty

  編寫的單元測試類,從unittest.TestCase繼承。其中,只有以test開頭的方法是測試方法。

  運行單元測試時,可以在測試文件中加入:

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

然后run。

  另一種,在命令行中輸入命令:

$ python -m unittest mydict_test ..... ---------------------------------------------------------------------- Ran 5 tests in 0.000sOK

第二種方法,可以一次運行多個測試文件,比較方便。

  setUp與tearDown:在每個測試方法前后分別被執行,避免在測試代碼中重復加入代碼。

  最后,單元測試要考慮到異常,代碼不能過于復雜,以免本身就有bug。

  • 文檔測試

  Python中可以提供實例文檔,在文件中編寫特定格式的注釋,調用doctest判斷程序是否會像注釋中那樣的運行。

class Dict(dict):'''Simple dict but also support access as x.y style.>>> d1 = Dict()>>> d1['x'] = 100>>> d1.x100>>> d1.y = 200>>> d1['y']200>>> d2 = Dict(a=1, b=2, c='3')>>> d2.c'3'>>> d2['empty']Traceback (most recent call last):...KeyError: 'empty'>>> d2.emptyTraceback (most recent call last):...AttributeError: 'Dict' object has no attribute 'empty''''def __init__(self, **kw):super(Dict, self).__init__(**kw)def __getattr__(self, key):try:return self[key]except KeyError:raise AttributeError(r"'Dict' object has no attribute '%s'" % key)def __setattr__(self, key, value):self[key] = valueif __name__=='__main__':import doctestdoctest.testmod()

然后run。如果什么都沒輸出,就說明編寫的doctest運行都是正確的。

??注:本文為學習廖雪峰Python入門整理后的筆記

轉載于:https://www.cnblogs.com/likely-kan/p/7517924.html

總結

以上是生活随笔為你收集整理的Day-10: 错误、调试和测试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。