Python学习笔记__8章错误、调试和测试__8.1章错误处理
# 這是學(xué)習(xí)廖雪峰老師python教程的學(xué)習(xí)筆記
1、概覽
我們?cè)谶\(yùn)行程序或編寫(xiě)函數(shù)時(shí),發(fā)生錯(cuò)誤后,系統(tǒng)都會(huì)返回錯(cuò)誤信息。我們可以通過(guò)某些機(jī)制,讓錯(cuò)誤信息更加明了
1.1、try
try機(jī)制的格式就是 try…except…finally。
try:? ?# try: 運(yùn)行這段代碼,若代碼有誤,就執(zhí)行except
??? print('try...')
??? r = 10 / 0
??? print('result:', r)
except ZeroDivisionError as e: ?# except:捕獲指定的錯(cuò)誤類(lèi)型并賦值給變量e。except可以有多個(gè)
??? print('except:', e)
finally:? # try 或 except 執(zhí)行完后,執(zhí)行finally
??? print('finally...')
注意:
Python的錯(cuò)誤其實(shí)也是class,所有的錯(cuò)誤類(lèi)型都繼承自BaseException,所以在使用except時(shí)需要注意的是,它不但捕獲該類(lèi)型的錯(cuò)誤,還把其子類(lèi)也“一網(wǎng)打盡”。比如:
try:
??? foo()
except ValueError as e:
??? print('ValueError')
except UnicodeError as e:
??? print('UnicodeError')
第二個(gè)except永遠(yuǎn)也捕獲不到UnicodeError,因?yàn)?/span>UnicodeError是ValueError的子類(lèi),如果有,也被第一個(gè)except給捕獲了。
?
1.2、調(diào)用棧
$ python3 err.py
Traceback (most recent call last):
? File "err.py", line 11, in <module>
??? main()
? File "err.py", line 9, in main
??? bar('0')
? File "err.py", line 6, in bar
??? return foo(s) * 2
? File "err.py", line 3, in foo
??? return 10 / int(s)
ZeroDivisionError: division by zero
調(diào)用棧就是系統(tǒng)自己返回的錯(cuò)誤信息。看調(diào)用棧,從上往下看。最后三行指明了錯(cuò)誤的根源
1.3、記錄錯(cuò)誤
如果不捕獲錯(cuò)誤,可以讓Python解釋器來(lái)打印出錯(cuò)誤堆棧,但程序也被結(jié)束了。
我們也可以捕獲錯(cuò)誤,把錯(cuò)誤堆棧打印出來(lái),然后分析錯(cuò)誤原因,同時(shí),讓程序繼續(xù)執(zhí)行下去。
Python內(nèi)置的logging模塊可以非常容易地記錄錯(cuò)誤信息。
import logging
def foo(s):
??? return 10 / int(s)? # 錯(cuò)誤根源
def bar(s):
??? return foo(s) * 2
def main():
??? try:
??????? bar('0')? # main()調(diào)用bar(),bar()調(diào)用foo()。
??? except Exception as e:
??????? logging.exception(e)
?
main()
print('END')
?
因?yàn)橛?logging.exception(e)。執(zhí)行 .py文件后。會(huì)繼續(xù)執(zhí)行,打印出“END”
1.4、拋出錯(cuò)誤
錯(cuò)誤是class,捕獲一個(gè)錯(cuò)誤就是捕獲到該class的一個(gè)實(shí)例。所以,錯(cuò)誤并不是憑空產(chǎn)生的,而是有意創(chuàng)建并拋出的。拋出的錯(cuò)誤既可以是Python的內(nèi)置函數(shù)定義的,也可以是我們自己定義的
1、第一種拋出:
# err_raise.py
class FooError(ValueError):? # 定義了一個(gè)錯(cuò)誤類(lèi)
??? pass
?
def foo(s):
??? n = int(s)
??? if n==0:
??????? raise FooError('invalid value: %s' % s)? # 拋出自己定義的錯(cuò)誤類(lèi)
??? return 10 / n
?
foo('0') # 調(diào)用函數(shù)
2、第二種拋出:
# err_reraise.py
def foo(s):
??? n = int(s)
??? if n==0:
??????? raise ValueError('invalid value: %s' % s)? # 拋出ValueError錯(cuò)誤
??? return 10 / n
?
def bar():
??? try:
??????? foo('0')
??? except ValueError as e: ?# 捕捉錯(cuò)誤
??????? print('ValueError!')
??????? raise # raise不帶參數(shù),把當(dāng)前錯(cuò)誤原樣拋出。因?yàn)檎{(diào)用了foo(),所以拋給foo()
?
bar() # 調(diào)用函數(shù)
ValueError!? # except捕獲錯(cuò)誤后的print
Traceback (most recent call last): ??#原樣拋出錯(cuò)誤,表現(xiàn)形式為協(xié)議棧
? File "<stdin>", line 1, in <module>
? File "<stdin>", line 3, in bar
? File "<stdin>", line 4, in foo
ValueError: invalid value: 0? ?# foo()拋出捕獲的錯(cuò)誤
?
1.5、錯(cuò)誤的轉(zhuǎn)換
在except中raise一個(gè)Error,可以把一種類(lèi)型的錯(cuò)誤轉(zhuǎn)化成另一種類(lèi)型
try:
??? 10 / 0
except ZeroDivisionError:
??? raise ValueError('input error!')
轉(zhuǎn)載于:https://blog.51cto.com/12758568/2116869
總結(jié)
以上是生活随笔為你收集整理的Python学习笔记__8章错误、调试和测试__8.1章错误处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Markdown批量发布到Github
- 下一篇: python3高阶函数:map(),re