一、異常處理
1、異常的概念
異常是錯誤發生的信號,一旦程序出錯,並且程序沒有處理這個錯誤,那個就會拋出異常,並且程序的運行隨即終止。
2、錯誤種類
分兩種,第一種是:語法錯誤,這種錯誤,根本過不了python解釋器的語法檢測,必須在程序執行前就改正。
常見語法錯誤:

#TypeError:int類型不可迭代
for i in 3: pass
#ValueError
num=input(">>: ") #輸入hello
int(num) #NameError
aaa #IndexError
l=['egon','aa'] l[3] #KeyError
dic={'name':'egon'} dic['age'] #AttributeError 屬性錯誤
class Foo:pass Foo.x #ZeroDivisionError:無法完成計算
res1=1/0 res2=1+'str' AttributeError 試圖訪問一個對象沒有的樹形,比如foo.x,但是foo沒有屬性x IOError 輸入/輸出異常;基本上是無法打開文件 ImportError 無法引入模塊或包;基本上是路徑問題或名稱錯誤 IndentationError 語法錯誤(的子類) ;代碼沒有正確對齊 IndexError 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5] KeyError 試圖訪問字典里不存在的鍵 KeyboardInterrupt Ctrl+C被按下 NameError 使用一個還未被賦予對象的變量 SyntaxError Python代碼非法,代碼不能編譯(個人認為這是語法錯誤,寫錯了) TypeError 傳入對象類型與要求的不符合 UnboundLocalError 試圖訪問一個還未被設置的局部變量,基本上是由於另有一個同名的全局變量, 導致你以為正在訪問它 ValueError 傳入一個調用者不期望的值,即使值的類型是正確的
第二種是:邏輯錯誤,這是我們今天重點需要探討的。
3、邏輯錯誤的異常處理
3.1、異常處理的意義:保證程序的健壯性與容錯性,即在遇到錯誤時程序不會崩潰。
3.2 、這里又可以分為兩種情況
<1>如果錯誤發生的條件是可預知的,我們需要用if進行處理:在錯誤發生之前進行預防。
AGE=10
while True: age=input('>>: ').strip() if age.isdigit(): #只有在age為字符串形式的整數時,下列代碼才不會出錯,該條件是可預知的
age=int(age) if age == AGE: print('you got it') break
<2>如果錯誤發生的條件是不可預知的,則需要用到try...except:在錯誤發生之后進行處理。
基本語法:
try: 被檢測的代碼塊 except 異常類型: try中一旦檢測到異常,就執行這個位置的邏輯
示例:

try: f = open('test.txt','r',encoding='utf-8') print(next(f),end=' ') print(next(f),end=' ') print(next(f),end=' ') print(next(f),end=' ') print(next(f),end=' ') print(next(f),end=' ') except StopIteration: print('迭代出錯')
二、try...except詳解
1、多分支:
被檢測的代碼塊拋出的異常有多種可能性,並且我們需要針對每一種異常類型都定制專門的處理邏輯。
s1 = 'hello'
try: int(s1) except IndexError as e: # 將異常信息傳給變量e
print(e) except KeyError as e: print(e) except ValueError as e: print(e)
2、萬能異常
被檢測的代碼塊拋出的異常有多種可能性,並且我們針對所有的處理邏輯只用一種就可以了。
s1 = 'hello'
try: int(s1) except Exception as e: print('發生異常',e)
3、可以在多分支后來一個Exception

try: #name
print('--->1') l = [1,2,3,4] #l[5]
print('--->2') d = {} #d['name']
print('---->3') except NameError as e: print('--->',e) except IndexError as e: print('--->',e) # list index out of range
except KeyError as e: print('--->',e) except Exception as e: print('萬能異常檢測方法') else: print('沒有發生異常時執行') finally: print('不管代碼塊是否有異常都會執行') print('====== end ======')
4、末尾加上finally的用處

try: f = open('test.txt','r',encoding='utf-8') print(next(f),end=' ') print(next(f),end=' ') print(next(f),end=' ') print(next(f),end=' ') print(next(f),end=' ') print(next(f),end=' ') finally: # 資源回收時使用,不論是否發生異常都會執行
f.close()
5、主動觸發異常:raise,異常類型值
class People: def __init__(self,name,age): if not isinstance(name,str): raise TypeError('名字必須為str類型') if not isinstance(age,int): raise TypeError('年齡必須為正整數') self.name = name self.age = age p = People('cc',21)
6、自定義異常
class EgonException(BaseException): def __init__(self,msg): self.msg=msg def __str__(self): return self.msg try: raise EgonException('類型錯誤') except EgonException as e: print(e)
7、斷言:assert 條件
assert 1 == 1
assert 1 == 2
小結:try...except
保證了程序的安全性,不至於一點錯誤就導致整個程序崩潰,將錯誤和正常工作分開,更容易組織代碼。