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