【廖雪峰Python学习笔记】错误、调试、测试
生活随笔
收集整理的這篇文章主要介紹了
【廖雪峰Python学习笔记】错误、调试、测试
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 錯誤處理
- 調試
- 單元測試unitcase
- 文檔測試
錯誤類型
- 程序編寫問題bug – 字符類型錯誤等
- 用戶輸入錯誤 – 輸入不符合規定的字符串
- 異常,程序運行時無法預測 – 磁盤滿了,無法寫
錯誤處理
錯誤處理機制:try…except…finally…
try運行可能會出錯的代碼,若出錯則后續代碼不再運行try中存在錯誤代碼時,執行except語句塊拋出異常finally可有可無,不論是否異常,最后都會執行- 所有錯誤類型均繼承自
BaseException - 不同
except可以對不同錯誤類型進行處理 except可以捕獲自身及子類的錯誤except可以跨越多層調用
try:print('try...')test_int = 10 / int('a') # 除法運算錯誤print('result = ', test_int) # 由于上一行代碼錯誤,try的后續代碼不再運行
except ZeroDivisionError as e: print('except: ', e)
except ValueError as e:print('ValueError:', e)
else:print('no error was found!')
finally:print('finally...')
print('END')
調用棧:出錯時,須分析錯誤的調用棧信息,以定位錯誤的位置
Traceback (most recent call last):…………
logging模塊可以記錄錯誤信息,且程序可繼續執行
import logging
def foo(s):return 10 / int(s)
def bar(s):return foo(s) * 2
def main():try:bar('0')except Exception as e:logging.exception(e)
main()
輸出結果:
ERROR:root:division by zero
Traceback (most recent call last):File "/Pratice/DEMO.py", line 8, in mainbar('0')File "/Pratice/DEMO.py", line 5, in barreturn foo(s) * 2File "/Pratice/DEMO.py", line 3, in fooreturn 10 / int(s)
ZeroDivisionError: division by zero
raise拋出一個錯誤的實例
def foo(s):n = int(s)if n==0:raise ValueError('invalid value: %s' % s)return 10 / ndef bar():try:foo('0')except ValueError as e:print('ValueError!')raisebar()
輸出結果:
Traceback (most recent call last):
ValueError!File "/Pratice/DEMO1.py", line 14, in <module>bar()File "/Pratice/DEMO1.py", line 9, in barfoo('0')File "/Pratice/DEMO1.py", line 4, in fooraise ValueError('invalid value: %s' % s)
ValueError: invalid value: 0
調試
使用print()調試,簡單粗暴,但是調試過后需要刪除調試代碼
assert()斷言
def foo(s):n = int(s)assert n != 0, 'n is zero' # 若‘n != 0’不成立,則拋出AssertionErrorreturn 10/sdef main():foo('0')
main()
輸出結果:
Traceback (most recent call last):File "/Pratice/DEMO2.py", line 8, in <module>main()File "/Pratice/DEMO2.py", line 7, in mainfoo('0')File "/Pratice/DEMO2.py", line 3, in fooassert n != 0, 'n is zero'
AssertionError: n is zero
tips:python -O DEMO2.py 可以將DEMO2.py中的assert當成pass來看
2. logging()記錄
輸出文件而不是拋出錯誤
可指定記錄信息的級別
通過簡單配置,一條語句可同時輸出到不同地方
import logging
# 指定記錄信息的級別 debug->info->warning->error
logging.basicConfig(level=logging.INFO) s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)
輸出結果:
INFO:root:n = 0
Traceback (most recent call last):File "/Pratice/DEMO3.py", line 7, in <module>print(10 / n)
ZeroDivisionError: division by zero
pdb調試器
讓程序以單步方式運行,隨時查看運行狀態
? python -m pdb DEMO.py # 使用調試器查看單步運行狀態
> /Users/amey/growingio/Pratice/DEMO.py(1)<module>()
-> import logging
(Pdb) l # l查看代碼1 -> import logging2 logging.basicConfig(level=logging.INFO)3 4 s = '0'5 n = int(s)6 logging.info('n = %d' % n)7 print(10 / n)
[EOF]
(Pdb) n # n -> 單步執行代碼
> /Users/amey/growingio/Pratice/DEMO.py(2)<module>()
-> logging.basicConfig(level=logging.INFO)
(Pdb) n # n -> 單步執行代碼
> /Users/amey/growingio/Pratice/DEMO.py(4)<module>()
-> s = '0'
(Pdb) p s # p 變量名 -> 查看變量
> '0'
(Pdb) q # q -> 結束調試
單元測試unitcase
setUp()和tearDown()方法,在調用一個測試方法前后分別執行
[eg:連接關閉數據庫]- 使用
python -m unittest test可以批量運行多個單元測試
編寫一個學生成績單元測試
import unittestclass Student(object):def __init__(self, name ,score):self.name = nameself.score = scoredef get_grade(self):if(self.score > 100 or self.score < 0 or type(self.score) != int):raise ValueErrorelif(self.score < 60):return 'C'elif(self.score < 80):return 'B'else:return 'A'class TestStudent(unittest.TestCase):def test_80_to_100(self):s1 = Student('Amey', 100)s2 = Student('Jimmy', 80)self.assertEqual(s1.get_grade(),'A')self.assertEqual(s2.get_grade(),'A')def test_60_to_800(self):s1 = Student('Bart', 79)s2 = Student('Cindy', 60)self.assertEqual(s1.get_grade(),'B')self.assertEqual(s2.get_grade(),'B')def test_0_to_60(self):s1 = Student('Dan', 59)s2 = Student('Lisa', 0)self.assertEqual(s1.get_grade(),'C')self.assertEqual(s2.get_grade(),'C')def test_invaild(self):s1 = Student('Jan', 101)s2 = Student('King', -1)with self.assertRaises(ValueError):s1.get_grade()with self.assertRaises(ValueError):s2.get_grade()if __name__ == '__main__':unittest.main()
測試結果:
? python -m unittest DEMO4
....
----------------------------------------------------------------------
Ran 4 tests in 0.000sOK
文檔測試
doctest模塊:可提取注視中的代碼并執行測試
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def fact(n):'''計算 1*2*3*...*n>>> fact(1)1>>> fact(-1)Traceback (most recent call last):File "/Pratice/demo.py", line 13, in <module>print(fact(-1))File "/Pratice/demo.py", line 7, in factraise ValueErrorValueError>>> fact(10)3628800'''if(n < 1):raise ValueErrorif(n == 1):return 1return n * fact(n-1)if __name__ == '__main__':import doctestdoctest.testmod()
總結
以上是生活随笔為你收集整理的【廖雪峰Python学习笔记】错误、调试、测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【廖雪峰Python学习笔记】面向对象高
- 下一篇: 【Python自动化测试】setupto