您好,登錄后才能下訂單哦!
邏輯錯誤: 算法寫錯了,函數或者類使用出錯
語法錯誤:變量名寫錯了,語法錯誤
本意就是意外情況
有一個前提,沒有出現上面的錯誤,也就是說程序寫的沒有問題,但在某些情況下,會出現一些意外,導致程序無法正常執行下去,異常時不可能避免的,如open函數操作一個文件,文件不存在,或者創建一個文件時已經存在了,或者訪問一個網絡文件,突然斷網了,這就是異常,時意外情況。
在高級編程語言中,一般都會有錯誤和異常的概念,異常是可以捕獲的,并被處理,但錯誤不能被捕獲
如下
此處是異常,其是Traceback
解決方式如下:
#!/usr/local/bin/python3.6
#coding:utf-8
try:
open('test200') # 以只讀的形式打開一個文件,其默認會拋出異常
except OSError as e:
print (e)
結果如下
上述出現的是語法錯誤導致的問題
#!/usr/local/bin/python3.6
#coding:utf-8
try:
def 0aa():
pass
except:
pass
結果如下
此處的錯誤是無法被捕獲的
#!/usr/local/bin/python3.6
#coding:utf-8
try:
f=open('test100') #此處是只讀方式打開的文件,不存在,會拋出異常,若此處異常,則下面的語句將不會被執行
print ('after')
except:# 如果沒有異常,則此處將不會被執行,此處相當于異常已經被處理掉了
print ('NOT FOUND File')
結果如下
1 raise 語句顯式拋出異常
2 python解釋器自己檢測到異常并引發他
#!/usr/local/bin/python3.6
#coding:utf-8
def div(x,y):
return x/y # 此處也叫除零異常
try:
div(1,0) # 此種異常成為運行時異常
except: # 此處不寫,默認匹配所有異常
print ('Error')
結果如下
#!/usr/local/bin/python3.6
#coding:utf-8
def div(x,y):
return x/y # 此處也叫除零異常
try:
div(1,0) # 此種異常成為運行時異常
except:
print ('Error')
結果如下
程序會在異常拋出的地方中斷。如果不捕獲,就會提前結束程序
raise 后面什么都沒有,表示拋出最近一個被激活的異常,如果沒有被激活的異常,則拋類型異常,少用
#!/usr/local/bin/python3.6
#coding:utf-8
try:
1/0 #產生異常
except:
try:
raise # 此處可捕獲的最近被激活的異常
except Exception as e:
print (e)
結果如下:
無參實例化
#!/usr/local/bin/python3.6
#coding:utf-8
try:
1/0 #產生異常
except:
try:
raise Exception #此處是無參實例化異常拋出,此處會將上述異常覆蓋,此下將不會有情況,此處拋出的是一個實例
except Exception as e:
print (e.__class__.mro()) # 此處__class__表示是獲取其實例對應的類,并通過mro進行調用處理
此處是進行有參實例化后的結果
#!/usr/local/bin/python3.6
#coding:utf-8
try:
1/0 #產生異常
except:
try:
raise Exception('My BDA') # 此處可捕獲的最近被激活的異常,此處可對異常進行相關的處理后進行拋出
except Exception as e:
print (e)
結果如下:
BaseException 是所有異常的祖先類,及就是所有異常的基類
#!/usr/local/bin/python3.6
#coding:utf-8
import sys
try:
sys.exit() # 此處調用的是系統退出的指令
except SystemExit: # 此處匹配SystemExit 系統退出命令
print ('exit')
結果如下
匹配其他非SystemExit父類的異常類
#!/usr/local/bin/python3.6
#coding:utf-8
import sys
try:
sys.exit() # 此處調用的是系統退出的指令
except FileNotFoundError: # 此處匹配SystemExit 系統退出命令,若匹配其他則不會被捕獲
print ('exit')
print ('outer') # 此處因為退出,因此此處不會被執行
如下
#!/usr/local/bin/python3.6
#coding:utf-8
import sys
try:
import time
while True:
time.sleep(3) # 此處是一個死循環,可通過外界CTRL+C 進行終止,則打印如下信息
pass
except KeyboardInterrupt:
print ('ctl + c')
print ('outer')
結果如下
Exception 是所有內建的,非系統退出的異常的基類,自定義類應該集成自它。
SyntaxError 語法錯誤,python將其歸類到異常下的Exception中,但其不能被捕獲。
ArithmeticError 所有算術計算引發的異常,其子類有除零異常情況等
LookupError 使用映射的鍵或序列的索引無效時引發的異常基類:IndexError,KeyError 等
自定義異常
#!/usr/local/bin/python3.6
#coding:utf-8
class MyException(Exception): # 自定義類,繼承至內部的基類
pass
try:
raise MyException() # 實例化調用并拋出異常
except MyException:
print (MyException.mro()) # 打印其祖先類列表
結果如下
NotImplemented 和 NotImplementedError
NotImplemented: 是一個值,相當于是一個None
NotImplementedError: 這是一個類,是一個異常,是拋出異常的時候使用的。
如下:
#!/usr/bin/poython3.6
#conding:utf-8
# this is test
print (type(NotImplemented))
print (type(NotImplementedError))
class A:
def show(self):
raise NotImplementedError
A().show()
#!/usr/local/bin/python3.6
#coding:utf-8
class MyException(Exception): # 自定義類,繼承至內部的基類
pass
try:
1/0 #此處異常后下面的語句將不會被執行
open('test100')
raise MyException() # 實例化調用并拋出異常
except MyException: #其匹配方式是從上向下進行匹配,若匹配到,則直接返回結果,下面的將不會被再次匹配
print (MyException.mro()) # 打印其祖先類列表
except ArithmeticError:
print ('除零錯誤')
except FileNotFoundError:
print ('文件不存在')
except:
print ('其他異常')
結果如下
#!/usr/local/bin/python3.6
#coding:utf-8
class MyException(Exception): # 自定義類,繼承至內部的基類
pass
try:
# 1/0 #此處異常后下面的語句將不會被執行
open('test100') #此處匹配文件異常
raise MyException() # 實例化調用并拋出異常
except MyException: #其匹配方式是從上向下進行匹配,若匹配到,則直接返回結果,下面的將不會被再次匹配
print (MyException.mro()) # 打印其祖先類列表
except ArithmeticError:
print ('除零錯誤')
except FileNotFoundError:
print ('文件不存在')
except:
print ('其他異常')
結果如下
#!/usr/local/bin/python3.6
#coding:utf-8
class MyException(Exception): # 自定義類,繼承至內部的基類
pass
try:
# 1/0 #此處異常后下面的語句將不會被執行
# open('test100') #此處匹配文件異常
raise MyException() # 實例化調用并拋出異常
except MyException: #其匹配方式是從上向下進行匹配,若匹配到,則直接返回結果,下面的將不會被再次匹配
print ('自定義異常') # 打印其祖先類列表
except ArithmeticError:
print ('除零錯誤')
except FileNotFoundError:
print ('文件不存在')
except:
print ('其他異常')
捕獲規則
捕獲是從上到下依次比較,如果匹配,則執行匹配的except語句,
如果被一個except語句捕獲,則其他的except語句不會再次被執行了
如果沒有任何一個except語句捕獲到這個異常,則該異常向外拋出
異常不能被捕獲的情況
#!/usr/local/bin/python3.6
#coding:utf-8
try:
1/0 #此處異常后下面的語句將不會被執行
except FileNotFoundError:
print ('文件不存在')
被拋出的異常,應該是異常的實例,可通過as字句進行獲取
#!/usr/local/bin/python3.6
#coding:utf-8
try:
1/0 #此處異常后下面的語句將不會被執行
except ArithmeticError as e: # 進行異常的捕獲并獲取
print (e,type(e))
#!/usr/local/bin/python3.6
#coding:utf-8
class MyException(Exception): # 自定義異常類
pass
try:
raise MyException # 拋出類實例,此處是一個空的實例
except MyException as e:
print (e,type(e)) # 獲取類,此處無法獲取實例的內容,因為上述沒有定義,此處只能獲取到其類型
結果如下
添加信息如下
#!/usr/local/bin/python3.6
#coding:utf-8
class MyException(Exception): # 自定義異常類
pass
try:
raise MyException('My Exception') # 拋出類實例,此處是一個空的實例
except MyException as e:
print (e,type(e)) # 獲取類,此處無法獲取實例的內容,因為上述沒有定義,此處只能獲取到其類型
結果如下
可定義時間等信息加入其中
#!/usr/local/bin/python3.6
#coding:utf-8
import datetime
class MyException(Exception): # 自定義異常類
pass
try:
raise MyException('My Exception') # 拋出類實例,此處是一個空的實例
except MyException as e:
print (e,type(e),datetime.datetime.now()) # 獲取類,此處無法獲取實例的內容,因為上述沒有定義,此處只能獲取到其類型
是必須被執行的語句
#!/usr/local/bin/python3.6
#coding:utf-8
import datetime
class MyException(Exception):
def __init__(self,xdata=10):
self.xdata=xdata
try:
raise MyException # 本身自己出錯,被底層服務捕獲,構造時出現的異常,因此類型異常時從此出現的
except ArithmeticError as e:
print (e,type(e),e.__class__,datetime.datetime.now().timestamp())
except OSError :
print ('操作系統異常')
finally: #此處是否拋出異常,此代碼都會被執行
print ('fin')
結果如下
發現在連接中出現的問題,可以在finally中進行處理,其處理的是最終的清理工作,資源的釋放工作,和上下文是一樣的
#!/usr/local/bin/python3.6
#coding:utf-8
try:
f = open('test.txt')
except FileNotFoundError as e:
print ('{} {} {}'.format(e.__class__,e.errno,e.strerror))
finally:
print ('清理工作')
f.close() # 上述的文件不存在,因此其f不存在,因此會報NameError的錯誤
修改方式如下 ,finally中添加異常處理
#!/usr/local/bin/python3.6
#coding:utf-8
try:
f = open('test.txt')
except FileNotFoundError as e:
print ('{} {} {}'.format(e.__class__,e.errno,e.strerror))
finally:
print ('清理工作')
try:
f.close() # 上述的文件不存在,因此其f不存在,因此會報NameError的錯誤
except NameError as e:
print (e)
#!/usr/local/bin/python3.6
#coding:utf-8
f=None
try:
f = open('test.txt')
except FileNotFoundError as e:
print ('{} {} {}'.format(e.__class__,e.errno,e.strerror))
finally:
print ('清理工作')
if f is not None:
f.close()
#!/usr/local/bin/python3.6
#coding:utf-8
try:
f = None # 此處定義f,此處定義和全局定義相同,但一般不建議這樣操作
f = open('test.txt')
except FileNotFoundError as e:
print ('{} {} {}'.format(e.__class__,e.errno,e.strerror))
finally:
print ('清理工作')
if f is not None:
f.close()
結果如下
#!/usr/local/bin/python3.6
#coding:utf-8
def a1():
try:
return 1 #此處的退出不會影響下面finally的執行
except:
pass
finally:
print ('fin')
print (a1())
結果如下
#!/usr/local/bin/python3.6
#coding:utf-8
def a1():
try:
1/0 #此處異常后,下面的return將不會被執行,默認返回為None
return "1" #此處的退出不會影響下面finally的執行
except: # 此處表示所有異常都捕獲
pass
finally:
print ('fin')
print ("result={}".format(a1())) # 此處抓取返回值
結果如下
#!/usr/local/bin/python3.6
#coding:utf-8
def a1():
try:
1/0 #此處異常后,下面的return將不會被執行,默認返回為None
return "1" #此處的退出不會影響下面finally的執行
except: # 此處表示所有異常都捕獲
print ('Error')
finally:
return 100 # 此處定義return,將會覆蓋上面的return,且此return下面的語句將不會被執行
print ("result={}".format(a1())) # 此處抓取返回值
結果如下
#!/usr/local/bin/python3.6
#coding:utf-8
def a1():
try:
1/0 # 此處的異常未被處理
finally:
print ('a1')
def a2():
try:
a1() # 此處調用同上面,返回異常
finally:
print ('a2')
a2() # 此處調用函數,返回異常,異常是逐漸向外擴張的
結果如下
#!/usr/local/bin/python3.6
#coding:utf-8
def a1():
try:
1/0 # 此處的異常未被處理
finally:
print ('a1')
def a2():
try:
a1() # 此處調用同上面,返回異常
except ArithmeticError as e: #在此處處理a1的異常
print ('a2',e)
finally:
print ('a2')
try:
a2() # 此處調用函數,返回異常,異常是逐漸向外擴張的
except ArithmeticError as e: #因為a2處已經處理了異常,此處不需要再次處理相關異常
print ('out',e)
結果如下
繼續拋出異常
#!/usr/local/bin/python3.6
#coding:utf-8
def a1():
try:
1/0 # 此處的異常未被處理
finally:
print ('a1')
def a2():
try:
a1() # 此處調用同上面,返回異常
except ArithmeticError as e: #在此處處理a1的異常
print ('a2',e)
raise e #此處持續拋出異常,使得后面繼續執行
finally:
print ('a2')
try:
a2() # 此處調用函數,返回異常,異常是逐漸向外擴張的
except ArithmeticError as e: #因為a2處已經處理了異常,此處不需要再次處理相關異常
print ('out',e)
結果如下
#!/usr/local/bin/python3.6
#coding:utf-8
def a1():
try:
1/0 # 此處的異常未被處理
finally:
print ('a1')
def a2():
try:
a1() # 此處調用同上面,返回異常
finally:
print ('a2')
open('aaaaaaaa') # 此處出現異常,則外邊會忽略上面的異常,而執行此異常
try:
a2() # 此處調用函數,返回異常,異常是逐漸向外擴張的
except ArithmeticError as e: #因為a2處已經處理了異常,此處不需要再次處理相關異常
print ('out',e)
except FileNotFoundError as e:
print ('file',e)
結果如下
finally 無法處理異常,其執行進行相關的清理工作
Finally 中出現異常若不管,則外層需要有異常處理和捕獲機制
線程級別的問題
#!/usr/local/bin/python3.6
#coding:utf-8
import threading
import time
def foo1():
try:
1/0
finally:
print ('foo1 fin')
def foo2():
time.sleep(4)
try:
foo1() #
finally:
print ('foo2 fin')
open('acdvsacdsad')
while True: # 上面的foo1() 不跑出異常,則此處的while True會一直執行,此處執行,則線程會一直執行,此處下面的會一直檢測,檢測狀態
#為存活狀態
time.sleep(1)
t=threading.Thread(target=foo2) # 創建線程對象,此處的foo2 會產生異常,t的線程是否會影響死線程
t.start()
while True: # 當前線程是死循環
time.sleep(1)
print ('-------------------------')
if t.is_alive():
print ('alive')
else:
print ('dead')
結果如下
拋出異常后會一直向上,直到線程處,若線程不管,則只會掛掉當前線程,不會影響主線程
主線程操作
#!/usr/local/bin/python3.6
#coding:utf-8
import threading
import time
def foo1():
try:
1/0
finally:
print ('foo1 fin')
def foo2():
time.sleep(4)
try:
foo1() #
finally:
print ('foo2 fin')
open('acdvsacdsad')
while True: # 上面的foo1() 不跑出異常,則此處的while True會一直執行,此處執行,則線程會一直執行,此處下面的會一直檢測,檢測狀態
#為存活狀態
time.sleep(1)
while True: # 當前線程是死循環
time.sleep(1)
print ('-------------------------')
foo2()
結果如下
結論
當前線程如果是主線程,則會導致進程直接退出
總結
內部捕獲不到異常,會向外層傳遞異常
但是如果內層有finally且其中有return,break語句,則異常就不會繼續向外拋出
異常捕獲時機
1 立即捕獲,不要將異常向外處理,需要立即返回一個明確的結果
#!/usr/local/bin/python3.6
#coding:utf-8
def a1():
try:
f=open('100')
except FileNotFoundError as e:
print (e)
return 1 # 若匹配此處則返回此值
except FileExistsError as e:
print (e)
return 2
finally:
print ('aaaa')
a1()
結果
#!/usr/local/bin/python3.6
#coding:utf-8
def getaint(data): # 數字的轉換
try:
res=int(data)
except Exception: #此處若有異常,則直接返回為0,此處是立即捕獲,立即處理
res=0
return res
2 邊界捕獲
封裝產生了邊界
如: 寫了一個模塊,用戶調用這個模塊的時候捕獲異常,模塊內部不需要捕獲,處理異常,一旦內部處理了,外部調用者就無法感知了
例如 open 函數,出現的異常交給調用者處理,文件存在了,就不需要創建了,看是否修改還是刪除
一般的,自己寫了一個類,使用了open函數,但是出現了異常不知道如何處理,就繼續向外拋出,一般說最外層也是邊界,必須處理這個異常,否則線程將會退出
一般的,給外部提供某些功能的函數是不建議在內部進行處理操作的
業務的分界,模塊的外部
6 else
try:
1/0
except Exception:
print ('except')
except:
pass
else: # 此處針對沒有異常時執行的動作
print ('else')
finally:
print ('fin')
結果如下
沒有任何異常發生時,執行
try:
<語句> #運行的代碼
except <異常類>:
<語句> # 捕獲某種異常的類型
except <異常類> as <變量名>:
<語句> # 捕獲某種類型的異常并獲取對象
else:
<語句> #如果沒有發生異常
1 如果try 中語句執行時發生異常,搜索except字句,并執行第一個匹配該異常的except字句
2 如果try中語句執行時發生異常,卻沒有匹配的except字句,異常將被遞交到外層try,如果外層不處理這個異常,異常將繼續向外層傳遞,如果都補處理該異常,則會傳遞到最外層,如果沒有處理,就終止異常所在的線程
3 如果try執行時沒有異常,則執行else字句中的語句
4 無論try中是否發生異常,finally字句最終都會被執行
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。