錯(cuò)誤和異常
錯(cuò)誤---->
- 語法錯(cuò)誤: 自己造孽, 寫錯(cuò)代碼! 錯(cuò)誤也是一種異常;
- 邏輯錯(cuò)誤: 程序運(yùn)行中, 在某些特定條件下, 不合適的數(shù)據(jù)引起程序出現(xiàn)錯(cuò)誤導(dǎo)致程序崩潰。
>>> c = int(input("請(qǐng)輸入數(shù)據(jù)"))
請(qǐng)輸入數(shù)據(jù)a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'a'
異常----> 執(zhí)行過程中出現(xiàn)的問題導(dǎo)致程序無法正常執(zhí)行
- 程序遇到算法或邏輯問題
-
運(yùn)行過程中計(jì)算機(jī)出現(xiàn)問題(內(nèi)存不足, 或I/O錯(cuò)誤)
錯(cuò)誤與異常的區(qū)別
為什么要處理異常
當(dāng)程序在運(yùn)行過程中,由于用戶的誤操作或者不合適的數(shù)據(jù)引發(fā)的程序錯(cuò)誤,讓代碼自己處理并保證程序的正常執(zhí)行。而不至于因?yàn)殄e(cuò)誤導(dǎo)致程序崩潰!提高代碼的健壯性!
異常處理方法
- 捕獲異常
- 斷言處理異常[測(cè)試異常信息]
語法
try # 嘗試, 將可能出現(xiàn)的異常的代碼, 包含在try中
except # 一旦出現(xiàn)異常, 代碼就會(huì)直接從出現(xiàn)異常的地方跳轉(zhuǎn)到except中執(zhí)行
else # 如果try中的代碼執(zhí)行沒有異常, 執(zhí)行完畢后, 就會(huì)執(zhí)行else中的代碼
finally # 不會(huì)是否出現(xiàn)異常, 都要在try中執(zhí)行完成之后執(zhí)行的代碼
try:
print('try...')
r = 10/0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print("finally...")
print("END")
------------------------------------
try...
except: division by zero
finally...
END
當(dāng)我們認(rèn)為某些代碼可能會(huì)出錯(cuò)時(shí), 就可以用try來運(yùn)行這段代碼,如果執(zhí)行出錯(cuò), 則后續(xù)代碼不會(huì)繼續(xù)執(zhí)行, 而是直接跳轉(zhuǎn)至錯(cuò)誤處理代碼, 即except語句模塊, 執(zhí)行完except后,如果有finally語句塊, 則執(zhí)行finally語句塊, 至此, 執(zhí)行完畢。
處理多個(gè)異常
錯(cuò)誤可能有多種,使用不同的except語句塊處理。
try:
print('try...')
r = 10/int('a')
print('result:', r)
except ValueError as e:
print('ValueError:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
finally:
print('finally...')
print('END')
------------------------------------------
try...
ValueError: invalid literal for int() with base 10: 'a'
finally...
END
使用else
try:
print('try...')
r = 10/int('2')
print('result:', r)
except ValueError as e:
print('ValueError:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
else:
print("no error")
finally:
print('finally...')
print('END')
--------------------------------------
try...
result: 5.0
no error
finally...
END
捕獲異常的好處
可以跨越多層調(diào)用, 比如main()調(diào)用foo(), foo()調(diào)用bar(), 結(jié)果bar()出錯(cuò)了, 這時(shí), 只要main()捕獲到了, 就可以處理:
def foo(s):
return 10/int(s)
def bar(s):
return foo(s)*2
def main():
try:
bar('0')
except Exception as e:
print('Error:', e)
finally:
print('finally...')
main()
--------------------------------------
Error: division by zero
finally...
也就是說,不需要在每個(gè)可能出錯(cuò)的地方去捕獲錯(cuò)誤,只要在合適的層次去捕獲錯(cuò)誤就可以了。這樣一來,就大大減少了寫try...except...finally的麻煩。
自定義異常
首先-代碼執(zhí)行過程中,出現(xiàn)了異?!鞠到y(tǒng)標(biāo)準(zhǔn)異?!俊拘畔⒉皇呛苊靼住?/p>
捕獲系統(tǒng)異常,創(chuàng)建一個(gè)自定義異常
拋出自定義異?!咀远x異常】【信息明確的錯(cuò)誤】
自定義異常的目的:轉(zhuǎn)換異常信息,將不明確的異常信息轉(zhuǎn)換成更加精確的異常信息
轉(zhuǎn)換異常信息:異常的傳遞~傳遞更加明確的異常,給后面的代碼進(jìn)行處理!
主動(dòng)拋出異常
在開發(fā)過程中, 主動(dòng)出現(xiàn)的一種錯(cuò)誤, 將錯(cuò)誤拋出給程序。
通過raise關(guān)鍵字, 拋出一個(gè)異常
斷言處理異常(調(diào)試)
斷言是一句必須等價(jià)于布爾真的判定;此外,發(fā)生異常也意味著表達(dá)式為假.這些工作類似于 C 語言預(yù)處理器中 assert 宏,但在 Python 中它們?cè)谶\(yùn)行時(shí)構(gòu)建(與之相對(duì)的是編譯期判別).
如果剛剛接觸斷言這個(gè)概念,無妨.斷言可以簡(jiǎn)簡(jiǎn)單單的想象為 raise-if 語句(更準(zhǔn)確的說是raise-if-not 語句).測(cè)試一個(gè)表達(dá)式,如果返回值是假,觸發(fā)異常.
斷言語句等價(jià)于這樣的 Python 表達(dá)式,如果斷言成功不采取任何措施(類似語句),否則觸發(fā)AssertionError(斷言錯(cuò)誤)的異常.assert 的語法如下:
assert expression[, arguments]
Python中何時(shí)使用斷言
凡是用print()來輔助查看的地方, 都可以用斷言來替代
def foo(s):
n = int(s)
assert n != 0, 'n is zero'
return 10/n
def main():
foo('0')
main()
----------------------------------------
Traceback (most recent call last):
File "異常.py", line 61, in <module>
main()
File "異常.py", line 59, in main
foo('0')
File "異常.py", line 55, in foo
assert n != 0, 'n is zero'
AssertionError: n is zero
assert的意思是, 表達(dá)式n != 0應(yīng)該是True,否則, 根據(jù)程序運(yùn)行的邏輯, 后面的代碼肯定出錯(cuò)。
如果斷言失敗, assert會(huì)拋出AssertionError
參考博客:http://blog.csdn.net/pipisorry/article/details/21841883
常見的異常
所有異常的超類: BaseException
標(biāo)準(zhǔn)異常的超類: Exception
常見的異常:

