異常處理
1.什麼是異常?
- 異常就是程序運行時發生錯誤的信號,異常發生以後的代碼就不執行了
2.python中的常見異常種類:
AttributeError 試圖訪問一個對象沒有的屬性,好比foo.x,但foo沒有屬性x
IOError 輸入/輸出異常;基本上是沒法打開文件
ImportError 沒法引入模塊或包;基本上是路徑問題或名稱錯誤
IndentationError 語法錯誤(的子類) ;代碼沒有正確對齊
IndexError 下標索引超出序列邊界,好比列表x只有三個元素,卻試圖訪問x[4]
KeyError 試圖訪問字典裏不存在的鍵
KeyboardInterrupt Ctrl+C被按下
NameError 使用一個還未被賦予對象的變量
SyntaxError Python代碼非法,代碼不能編譯
TypeError 傳入對象類型與要求的不符合
UnboundLocalError 試圖訪問一個還未被設置的局部變量,基本上是因爲另外有一個同名的全局變量,致使你覺得正在訪問它
ValueError 傳入一個調用者不指望的值,即便值的類型是正確的
3.異常處理:
python解釋器檢測到錯誤時就會觸發異常。
若是異常觸發後沒被處理,程序就在當前異常處終止,後面的代碼不會運行了。
你能夠編寫異常處理的代碼,專門用來捕捉這個異常,若是捕捉成功則進入另一個處理分支,執行你爲其定製的邏輯,使程序不會崩潰,這就是異常處理。
異常是由程序的錯誤引發的,語法上的錯誤跟異常處理無關,必須在程序運行前就修正。
1、使用if判斷來進行異常處理:
num1=input('>>: ') #輸入一個字符串試試
if num1.isdigit():
int(num1) #咱們的正統程序放到了這裏,其他的都屬於異常處理範疇
elif num1.isspace():
print('輸入的是空格,執行這裏的邏輯')
elif len(num1) == 0:
print('輸入的是空,執行這裏的邏輯')
else:
print('其餘狀況,執行這裏的邏輯')
總結:
1.if判斷式的異常處理只能針對某一段代碼,對於不一樣的代碼段的相同類型的錯誤你須要寫重複的if來進行處理。
2.在你的程序中頻繁的寫與程序自己無關,與異常處理有關的if,會使得你的代碼可讀性極其的差
2、python爲每一種異常定製了一個類型,而後提供了一種特定的語法結構用來進行異常處理
【1】:基本語法
try:
被檢測的代碼塊
except 異常類型:
代碼塊 #try中一旦檢測到異常,就執行這個位置的邏輯
#示例1:
l1 = [11,22,33,44,55,66,77,88,99,1111,1133,15652]
obj = iter(l1) # 將可迭代對象轉化成迭代器
while 1:
try:
print(next(obj))
except StopIteration:
break
#示例2:
f = open('pick多數據',mode='rb')
while True:
try:
print(pickle.load(f))
except EOFError:
break
f.close()
【2】異常類只能用來處理指定的異常狀況,若是非指定異常則沒法處理。
# 未捕獲到異常,程序直接報錯
s1 = 'hello world'
try:
int(s1)
except IndexError as e:
print(e)
#結果:ValueError: invalid literal for int() with base 10: 'hello world'
【3】多分支
s1 = 'hello world'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
#結果:invalid literal for int() with base 10: 'hello world'
【4】萬能異常
s1 = 'hello world'
try:
int(s1)
except Exception as e:
print(e)
#結果:
invalid literal for int() with base 10: 'hello world'
1.若是你想要的效果是,不管出現什麼異常,咱們統一丟棄,或者使用同一段代碼邏輯去處理他們,那麼只有一個Exception就足夠了。
s1 = 'hello world'
try:
int(s1)
except Exception as e:
print(e) #丟棄或者執行其餘邏輯
#若是你統一用Exception能夠捕捉全部異常,但你在處理全部異常時都必須使用同一個邏輯去處理(這裏說的邏輯即當前expect下面的代碼塊)
2.若是你想要的效果是,對於不一樣的異常咱們須要定製不一樣的處理邏輯,那就須要用到多分支了。
#多分支:
s1 = 'hello world'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
#多分支 + Exception
s1 = 'hello world'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
except Exception as e:
print(e)
【5】異常的其餘結構:
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
else:
print('try內代碼塊沒有異常則執行此代碼')
finally:
print('不管異常與否,都會執行此代碼,一般是進行清理工做')
【6】主動觸發異常/主動拋異常
try:
raise TypeError('類型錯誤')
except Exception as e:
print(e)
【7】自定義異常
class My_Exception(BaseException):
def __init__(self,msg):
self.msg=msg
def __str__(self):
return self.msg
try:
raise My_Exception('類型錯誤')
except My_Exception as e:
print(e)
【8】:斷言
# assert 條件
assert 1 == 1
assert 1 == 2
【9】小結:
使用try..except的方式:
1:把錯誤處理和真正的工做分開來;
2:代碼更易組織,更清晰,複雜的工做任務更容易實現;
3:毫無疑問更安全了,不至於因爲一些小的疏忽而使程序意外崩潰了;
何時用異常處理?
try...except應該儘可能少用,由於它自己就是你附加給你的程序的一種異常處理的邏輯,與你的主要的工做是沒有關係的。
加多了,會致使你的代碼可讀性變差,只有在有些異常沒法預知的狀況下,才應該加上try...except,其餘的邏輯錯誤應該儘可能修正。