欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Python中異常機制的示例分析

小編給大家分享一下Python中異常機制的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)公司2013年開創(chuàng)至今,先為井岡山等服務(wù)建站,井岡山等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為井岡山企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

一、對異常的理解

1、什么是異常

??異常即“與正常情況不同”,何為正常?正常便是解釋器在解釋代碼時,我們所編寫的代碼符合解釋器定義的規(guī)則,即為正常,當解釋器發(fā)現(xiàn)某段代碼符合語法但有可能出現(xiàn)不正常的情況時,解釋器便會發(fā)出一個事件,中斷程序的正常執(zhí)行。這個中斷的信號便是一個異常信號。所以,總體解釋就是,在解釋器發(fā)現(xiàn)到程序出現(xiàn)錯誤的時候,則會產(chǎn)生一個異常,若程序沒有處理,則會將該異常拋出,程序的運行也隨之終止。我們可以在一個空白的.py文件中寫一句int(“m”),運行后結(jié)果如下。
Python中異常機制的示例分析

??這一串字體為解釋器拋出的一系列錯誤信息,因為int()傳入的參數(shù)只支持數(shù)字字符串和數(shù)字,顯然‘m’不屬于數(shù)字字符串傳入?yún)?shù)錯誤所以解釋器報“valueError”的錯誤。

2、錯誤和異常的區(qū)別

??對于python錯誤的概述:它指的是代碼運行前的語法或邏輯錯誤。拿常規(guī)語法錯誤來說,當我們編寫的代碼過不了語法檢測時,則會直接出現(xiàn)語法錯誤,必須在程序執(zhí)行前就改正,不然寫的代碼將毫無意義,代碼是不運行的,也無法捕獲得到。舉個例子,在.py文件輸入if a = 1 print(“hello”),輸出結(jié)果如下:

  Traceback (most recent call last):
  	File "E:/Test_code/test.py",line 1
    	if a = 1 print("hello")
                ^SyntaxError: invalid syntax

??函數(shù) print() 被檢查到有錯誤,是它前面缺少了一個冒號 : ,所以解析器會復現(xiàn)句法錯誤的那行代碼,并用一個小“箭頭”指向行里檢測到的第一個錯誤,所以我們可以直接找到對應(yīng)的位置修改其語法。當然除了語法錯誤,還有很多程序奔潰的錯誤,如內(nèi)存溢出等,這類錯誤往往比較隱蔽。
??相比于錯誤,python異常主要在程序執(zhí)行過程中,程序遇見邏輯或算法問題,這時解釋器如果可以處理,則沒問題,如果處理不了,便直接終止程序,便將異常拋出,如第1小點的int(‘m’)例子,因為參數(shù)傳入錯誤導致程序出錯。這種因為邏輯產(chǎn)生的異常五花八門,還好我們的解釋器都內(nèi)置好了各種異常的種類,讓我們知道是什么樣的異常出現(xiàn),好讓我們“對癥下藥”。
??這里注意一點,上述語法錯誤是可識別的錯誤,所以解釋器也會默認拋出一個SyntaxError異常信息反饋給程序員。所以本質(zhì)上大部分錯誤都是可被輸出打印的,只是因為錯誤代碼不運行,也就沒法處理,所以捕獲錯誤的異常信息就變得沒意義。

3、常見python異常種類

??這里貼上我們在寫代碼時最常見的異常類型,如果遇到其他種類的異常,當然是選擇白度啦~

異常名稱名稱解析
BaseException所有異常的基類
SystemExit解釋器請求退出
KeyboardInterrupt用戶中斷執(zhí)行(通常是輸入^C)
Exception常規(guī)錯誤的基類
StopIteration迭代器沒有更多的值
GeneratorExit生成器(generator)發(fā)生異常來通知退出
StandardError所有的內(nèi)建標準異常的基類
ArithmeticError所有數(shù)值計算錯誤的基類
FloatingPointError浮點計算錯誤
OverflowError數(shù)值運算超出最大限制
ZeropisionError除(或取模)零 (所有數(shù)據(jù)類型)
AssertionError斷言語句失敗
AttributeError對象沒有這個屬性
EOFError沒有內(nèi)建輸入,到達EOF 標記
EnvironmentError操作系統(tǒng)錯誤的基類
IOError輸入/輸出操作失敗
OSError操作系統(tǒng)錯誤
WindowsError系統(tǒng)調(diào)用失敗
ImportError導入模塊/對象失敗
LookupError無效數(shù)據(jù)查詢的基類
IndexError序列中沒有此索引(index)
KeyError映射中沒有這個鍵
MemoryError內(nèi)存溢出錯誤(對于Python 解釋器不是致命的)
NameError未聲明/初始化對象 (沒有屬性)
UnboundLocalError訪問未初始化的本地變量
ReferenceError弱引用(Weak reference)試圖訪問已經(jīng)垃圾回收了的對象
RuntimeError一般的運行時錯誤
NotImplementedError尚未實現(xiàn)的方法
SyntaxError Python語法錯誤
IndentationError縮進錯誤
TabError Tab和空格混用
SystemError一般的解釋器系統(tǒng)錯誤
TypeError對類型無效的操作
ValueError傳入無效的參數(shù)
UnicodeError Unicode相關(guān)的錯誤
UnicodeDecodeError Unicode解碼時的錯誤
UnicodeEncodeError Unicode編碼時錯誤
UnicodeTranslateError Unicode轉(zhuǎn)換時錯誤
Warning警告的基類
DeprecationWarning關(guān)于被棄用的特征的警告
FutureWarning關(guān)于構(gòu)造將來語義會有改變的警告
OverflowWarning舊的關(guān)于自動提升為長整型(long)的警告
PendingDeprecationWarning關(guān)于特性將會被廢棄的警告
RuntimeWarning可疑的運行時行為(runtime behavior)的警告
SyntaxWarning可疑的語法的警告
UserWarning用戶代碼生成的警告

二、python五大異常處理機制

??我們明白了什么是異常后,那么發(fā)現(xiàn)異常后怎么處理,便是我們接下來要解決的問題。這里將處理異常的方式總結(jié)為五種。

1、默認異常處理機制

??“默認”則說明是解釋器默認做出的行為,如果解釋器發(fā)現(xiàn)異常,并且我們沒有對異常進行任何預(yù)防,那么程序在執(zhí)行過程中就會中斷程序,調(diào)用python默認的異常處理器,并在終端輸出異常信息。剛才舉過的例子:int(“m”),便是解釋器因為發(fā)現(xiàn)參數(shù)傳入異常,這種異常解釋器“無能為力”,所以它最后中斷了程序,并將錯誤信息打印輸出,告訴碼農(nóng)朋友們:你的程序有bug!!!

2、try…except…處理機制

??我們把可能發(fā)生錯誤的語句放在try語句里,用except來處理異常。每一個try,都必須至少有一個或者多個except。舉一個最簡單的例子如下,在try訪問number的第500個元素,很明顯數(shù)組越界訪問不了,這時候解釋器會發(fā)出異常信號:IndexError,接著尋找后面是否有對應(yīng)的異常捕獲語句except ,如果有則執(zhí)行對應(yīng)的except語句,待except語句執(zhí)行完畢后,程序?qū)⒗^續(xù)往下執(zhí)行。如果沒有對應(yīng)的except語句,即用戶沒有處理對應(yīng)的異常,這時解釋器會直接中斷程序并將錯誤信息打印輸出

number = 'hello'try:	print(number[500])	#數(shù)組越界訪問except IndexError:	print("下標越界啦!")except NameError:	print("未聲明對象!")print("繼續(xù)運行...")

輸出結(jié)果如下,因為解釋器發(fā)出異常信號是IndexError,所以執(zhí)行下標越界語句。

下標越界啦!
繼續(xù)運行...

??為了解鎖更多用法,我們再將例子改一下,我們依然在try訪問number的第500個元素,造成訪問越界錯誤,這里的except用了as關(guān)鍵字可以獲得異常對象,這樣子便可獲得錯誤的屬性值來輸出信息。

number = 'hello'try:	print(number[500])	#數(shù)組越界訪問except IndexError as e:	print(e)except Exception as e:	#萬能異常
	print(e)except:			  	 #默認處理所有異常
	print("所有異常都可處理")print("繼續(xù)運行...")

輸出結(jié)果如下所示,會輸出系統(tǒng)自帶的提示錯誤:string index out of range,相對于解釋器因為異常自己拋出來的一堆紅色刺眼的字體,這種看起來舒服多了(能夠“運籌帷幄”的異常才是好異常嘛哈哈哈)。另外這里用到“萬能異常”Exception,基本所有沒處理的異常都可以在此執(zhí)行。最后一個except表示,如果沒有指定異常,則默認處理所有的異常。

string index out of range繼續(xù)運行...

3、try…except…finally…處理機制

??finally語句塊表示,無論異常發(fā)生與否,finally中的語句都要執(zhí)行完畢。也就是可以很霸氣的說,無論產(chǎn)生的異常是被except捕獲到處理了,還是沒被捕獲到解釋器將錯誤輸出來了,都統(tǒng)統(tǒng)要執(zhí)行這個finally。還是原來簡單的例子加上finally語句塊如下,代碼如下:

number = 'hello'try:	print(number[500])	#數(shù)組越界訪問,拋出IndexError異常except IndexError:	print("下標越界啦!")finally:	print("finally!")print("繼續(xù)運行...")		#運行

結(jié)果如下,數(shù)據(jù)越界訪問異常被捕獲到后,先執(zhí)行except 語句塊,完畢后接著執(zhí)行了finally語句塊。因為異常被執(zhí)行,所以后面代碼繼續(xù)運行。

下標越界啦!finally!
繼續(xù)運行...

??對try語句塊進行修改,打印abc變量值,因為abc變量沒定義,所以會出現(xiàn)不會被捕獲的NameError異常信號,代碼如下所示:

number = 'hello'try:	print(abc)	#變量未被定義,拋出NameError異常except IndexError:	print("下標越界啦!")finally:	print("finally!")print("繼續(xù)運行...")	#不運行

結(jié)果如下,因為NameError異常信號沒法被處理,所以解釋器將程序中斷,并將錯誤信息輸出,但這過程中依然會執(zhí)行finally語句塊的內(nèi)容。因為程序被迫中斷了,所以后面代碼不運行。

finally!	#異常沒被捕獲,也執(zhí)行了finallyTraceback (most recent call last):
	File "E:/Test_code/test.py",line 3,in <module>
   		print("abc")NameError: name 'abc' is not defined

??理解到這里,相信:try…finally…這種機制應(yīng)該也不難理解了,因為省略了except 捕獲異常機制,所以異常不可能被處理,解釋器會將程序中斷,并將錯誤信息輸出,但finally語句塊的內(nèi)容依然會被執(zhí)行。例子代碼如下:

number = 'hello'try:	print(abc)	#變量未被定義,拋出NameError異常finally:	print("finally!")print("繼續(xù)運行...")

運行結(jié)果:

finally!	#異常沒被捕獲,也執(zhí)行了finallyTraceback (most recent call last):
	File "E:/Test_code/test.py",line 3,in <module>
   		print("abc")NameError: name 'abc' is not defined

4、assert斷言處理機制

??assert語句先判斷assert后面緊跟的語句是True還是False,如果是True則繼續(xù)往下執(zhí)行語句,如果是False則中斷程序,將錯誤信息輸出。

assert 1 == 1 	#為True正常運行assert 1 == 2	#為False,終止程序,錯誤信息輸出

5、with…as處理機制

??with…as一般常用在文件處理上,我們平時在使用類似文件的流對象時,使用完畢后要調(diào)用close方法關(guān)閉,很麻煩,這里with…as語句提供了一個非常方便且人性的替代方法,即使突發(fā)情況也能正常關(guān)閉文件。舉個例子代碼如下,open打開文件后將返回的文件流對象賦值給fd,然后在with語句塊中使用。

with open('e:/test.txt','r') as fd:
	fd.read()
	print(abc)	#變量未被定義,程序終止,錯誤信息輸出print("繼續(xù)運行...")

??正常情況下,這里的with語句塊完畢之后,會自動關(guān)閉文件。但如果with語句執(zhí)行中發(fā)生異常,如代碼中的變量未定義異常,則會采用默認異常處理機制,程序終止,錯誤信息輸出,后面代碼不被運行,文件也會正常關(guān)閉。

三、python異常自定義

??說了這么多異常的使用,終于可以回到我前言所說的在實際項目中存在的問題,即錯誤碼的返回和數(shù)值的返回是沖突的(因為錯誤碼也是數(shù)值),這時候便可以用異常的拋出和捕獲來完成錯誤碼的傳遞,即try和except 。但系統(tǒng)發(fā)生異常時拋出的是系統(tǒng)本身定義好的異常類型,跟自己的錯誤碼又有何關(guān)系?這就是我接下來要說的內(nèi)容:如何定義自己的異常并且能夠被except 所捕獲

1、異常自定義

??實際開發(fā)中,有時候系統(tǒng)提供的異常類型往往都不能滿足開發(fā)的需求。這時候就要使用到異常的自定義啦,你可以通過創(chuàng)建一個新的異常類來擁有自己的異常。自己定義的異常類繼承自 Exception 類,可以直接繼承,或者間接繼承。栗子舉起來:

class MyException(Exception):
    '''自定義的異常類'''
    def __init__(self, error_num):	#異常類對象的初始化屬性
        self.error_num = error_num    def __str__(self):				#返回異常類對象說明信息
        err_info = ['超時錯誤','接收錯誤']
        return err_info[self.error_num]

??該類繼承自Exception 類,并且新類的名字為MyException,這跟前面我們一直在用的IndexError這個異常類一樣,都是繼承自Exception 類。__init__為構(gòu)造函數(shù),當我們創(chuàng)建對象時便會自動調(diào)用,__str__為對象說明信息函數(shù),當使用print輸出對象的時候,只要自己定義了__str__方法,那么就會打印從在這個方法中return的數(shù)據(jù)。
??即print(MyException(0))時,便可打印“超時錯誤”這個字符串,print(MyException(1))時,便可打印“接收錯誤”這個字符串,心細的你應(yīng)該可以理解,MyException(x)為臨時對象(x是傳入錯誤碼參數(shù),這里只定義了0和1),與a = MyException(x),a為對象一個樣子 。這里有一個好玩的說法,在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法。

2、異常拋出raise

??現(xiàn)在我們自己定義的錯誤定義好了(上面的MyException),怎么能像IndexError一樣讓except捕獲到呢?于是乎raise關(guān)鍵字派上用場。我們在異常機制中用try…except時,一般都是將可能產(chǎn)生的錯誤代碼放到try語句塊中,這時出現(xiàn)異常則系統(tǒng)便會自動將其拋出,比如IndexError,這樣except就能捕獲到,所以我們只要將自定義的異常在需要的時候?qū)⑵鋻伋黾纯伞?br/>??raise 唯一的一個參數(shù)指定了要被拋出的異常。它必須是一個異常的實例或者是異常的類(也就是 Exception 的子類),那么我們剛剛定義的異常類就可以用啦,舉個簡單例子:

try:
    raise MyException(0)	# 自己定義的錯誤類,將錯誤碼為0的錯誤拋出except MyException as e:
    print(e) 	  			# 輸出的是__str__返回的內(nèi)容,即“超時錯誤”

??這里我直接將自己定義的錯誤拋出,…as e就是把得到的錯誤當成對象e,這樣才可以訪問其屬性和方法。因為自己定義的錯誤中可以支持多個錯誤碼(本質(zhì)還是MyException這個錯誤),所以便可實現(xiàn)傳入不同錯誤碼就可打印不同錯誤信息。

3、異常捕獲

??只要我們在try中將錯誤raise出來,except就可以捕獲到(當然,異常必須是Exception 子類才能被捕獲),將前面兩個例子整合起來,代碼如下:

'''錯誤碼:0代表超時錯誤,1代表接收錯誤'''class MyException(Exception):
    '''自定義的異常類'''
    def __init__(self, error_num):	# 異常類對象的初始化屬性
        self.error_num= error_num    def __str__(self):				# 返回異常類對象指定錯誤碼的信息
        err_info = ['超時錯誤','接收錯誤']
        return err_info[self.error_num]def fun()
	raise MyException(1) 			# 拋出異常對象,傳入錯誤碼1def demo_main():
    try:
        fun()
    except MyException as ex:		# 這里要使用MyException進行捕獲,對象為ex
        print(ex) 	   				# 輸出的是__str__部分返回的內(nèi)容,即“接收錯誤”
        print(ex.error_num) 		# 輸出的是__init__中定義的error_num,即1demo_main()							#此處開始運行

??代碼從demo_main函數(shù)開始執(zhí)行,進入try語句塊,語句塊中的fun()函數(shù)模擬代碼運行失敗時raise 自定義的異常,except 正常接收后通過as 關(guān)鍵字得到異常對象,訪問該異常對象,便可正常輸出自定義的異常信息和自定義的錯誤碼。

四、異常使用注意事項

此注意事項參考博文:異常機制使用細則.

1、不要太依賴異常機制

??python 的異常機制非常方便,對于信息的傳遞中十分好用(這里信息的傳遞主要有三種,參數(shù)傳遞,全局變量傳遞,以及異常機制傳遞),但濫用異常機制也會帶來一些負面影響。過度使用異常主要表現(xiàn)在兩個方面:①把異常和普通錯誤混淆在一起,不再編寫任何錯誤處理代碼,而是以簡單地引發(fā)異常來代苦所有的錯誤處理。②使用異常處理來代替流程控制。例子如下:

buf = "hello"#例1:使用異常處理來遍歷arr數(shù)組的每個元素try:
    i = 0    
    while True:
        print (buf [i])
        i += 1except:
    pass#例2:使用流程控制避免下標訪問異常i = 0while i < len(buf ):
    print(buf [i])
    i += 1

??例1中假如循環(huán)過度便會下標訪問異常,這時候把錯誤拋出,再進行一系列處理,顯然是不可取的,因為異常機制的效率比正常的流程控制效率差,顯然例2中簡單的業(yè)務(wù)流程就可以避開這種錯誤。所以不要熟悉了異常的使用方法后,遇到這種簡單邏輯,便不管三七二十一引發(fā)異常后再進行解決。對于完全己知的錯誤和普通的錯誤,應(yīng)該編寫處理這種錯誤的代碼,增加程序的健壯性。只有對于外部的、不能確定和預(yù)知的運行時錯誤才使用異常

2、不要在 try 塊中引入太多的代碼

??在 try 塊里放置大量的代碼,這看上去很“簡單”,代碼框架很容易理解,但因為 try 塊里的代碼過于龐大,業(yè)務(wù)過于復雜,就會造成 try 塊中出現(xiàn)異常的可能性大大增加,從而導致分析異常原因的難度也大大增加。
??而且當塊過于龐大時,就難免在 try 塊后緊跟大量的 except 塊才可以針對不同的異常提供不同的處理邏輯。在同一個 try 塊后緊跟大量的 except 塊則需要分析它們之間的邏輯關(guān)系,反而增加了編程復雜度。所以,可以把大塊的 try 塊分割成多個小塊,然后分別捕獲并處理異常。

3、不要忽略捕獲到的異常

??不要忽略異常!既然己捕獲到異常,那么 except 塊理應(yīng)做些有用的事情,及處理并修復異常。except 塊整個為空,或者僅僅打印簡單的異常信息都是不妥的!具體的處理方式為:
處理異常。對異常進行合適的修復,然后繞過異常發(fā)生的地方繼續(xù)運行;或者用別的數(shù)據(jù)進行計算,以代替期望的方法返回值;或者提示用戶重新操作,總之,程序應(yīng)該盡量修復異常,使程序能恢復運行。
重新引發(fā)新異常。把在當前運行環(huán)境下能做的事情盡量做完,然后進行異常轉(zhuǎn)譯,把異常包裝成當前層的異常,重新傳給上層調(diào)用者。
在合適的層處理異常
。如果當前層不清楚如何處理異常,就不要在當前層使用 except 語句來捕獲該異常,讓上層調(diào)用者來負責處理該異常。

以上是“Python中異常機制的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

網(wǎng)站題目:Python中異常機制的示例分析
瀏覽地址:http://chinadenli.net/article36/gephpg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作定制開發(fā)做網(wǎng)站營銷型網(wǎng)站建設(shè)網(wǎng)站制作網(wǎng)站營銷

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司