1. 異常
(1) 異常處理
#沒有異常處理
num = int('abc')
print(num) #報錯
#異常處理
try:
num = int('abc') #try里的代碼是受保護的
print(num)
except Exception as e:
print(e) #輸出invalid literal for int() with base 10: 'abc',程序正常運行
e是由Exception類實例化的一個對象
class Exception(BaseException):
""" Common base class for all non-exit exceptions. """
def __init__(self, *args, **kwargs): # real signature unknown
pass
@staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass
(2) 異常分類
Exception是萬能的異常捕捉方法,可以捕捉到任何錯誤。
li = []
inp = input('請輸入內容:')
try:
li = []
li[999]
except IndexError as e: # 特殊異常需要優先匹配
print('索引錯誤')
except Exception as e:
print(e)
| 常見異常 | |
|---|---|
| AttributeError | 試圖訪問一個對象沒有的樹形,比如foo.x,但是foo沒有屬性x |
| IOError | 輸入/輸出異常;基本上是無法打開文件 |
| ImportError | 無法引入模塊或包;基本上是路徑問題或名稱錯誤 |
| IndentationError | 語法錯誤(的子類) ;代碼沒有正確對齊 |
| IndexError | 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5] |
| KeyError | 試圖訪問字典里不存在的鍵 |
| KeyboardInterrupt | Ctrl+C被按下 |
| NameError | 使用一個還未被賦予對象的變量 |
| SyntaxError | Python代碼非法,代碼不能編譯(個人認為這是語法錯誤,寫錯了) |
| TypeError | 傳入對象類型與要求的不符合 |
| UnboundLocalError | 試圖訪問一個還未被設置的局部變量,基本上是由於另有一個同名的全局變量,導致你以為正在訪問它 |
| ValueError | 傳入一個調用者不期望的值,即使值的類型是正確的 |
Python的錯誤其實也是class,所有的錯誤類型都繼承自BaseException,所以在使用except時需要注意的是,它不但捕獲該類型的錯誤,還把其子類也“一網打盡”。比如:
try:
foo()
except ValueError as e:
print('ValueError')
except UnicodeError as e:
print('UnicodeError')
第二個except永遠也捕獲不到UnicodeError,因為UnicodeError是ValueError的子類,如果有,也被第一個except給捕獲了。
Python所有的錯誤都是從BaseException類派生的,常見的錯誤類型和繼承關系看這里:
https://docs.python.org/3/library/exceptions.html#exception-hierarchy
使用try...except捕獲錯誤還有一個巨大的好處,就是可以跨越多層調用,比如函數main()調用foo(),foo()調用bar(),結果bar()出錯了,這時,只要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...')
也就是說,不需要在每個可能出錯的地方去捕獲錯誤,只要在合適的層次去捕獲錯誤就可以了。這樣一來,就大大減少了寫try...except...finally的麻煩。
(3) 異常實例
#IndexError
dic = ["wupeiqi", 'alex']
try:
dic[10]
except IndexError, e:
print e
#KeyError
dic = {'k1':'v1'}
try:
dic['k20']
except KeyError, e:
print e
#ValueError
s1 = 'hello'
try:
int(s1)
except ValueError, e:
print e
(4) 異常的結構
完整的基本結構如下
try:
# 主代碼塊
pass
except KeyError as e:
# 異常時,執行該塊
pass
else:
# 主代碼塊執行完,執行該塊
pass
finally:
# 無論異常與否,最終執行該塊
pass
(5) 主動觸發異常
try:
raise Exception('錯誤了。。。')
except Exception as e:
print e
(6) 自定義異常
class WupeiqiException(Exception):
def __init__(self, msg):
self.message = msg
def __str__(self):
return self.message
try:
raise WupeiqiException('我的異常')
except WupeiqiException,e:
print e
(7) 斷言
# assert 條件
assert 1 == 1 #條件成立程序正常運行
assert 1 == 2 #不成里就會報錯,程序就異常
