91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中異常機制的示例分析

發布時間:2021-03-10 10:07:48 來源:億速云 閱讀:309 作者:小新 欄目:編程語言

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

一、對異常的理解

1、什么是異常

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

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

2、錯誤和異常的區別

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

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

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

3、常見python異常種類

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

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

二、python五大異常處理機制

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

1、默認異常處理機制

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

2、try…except…處理機制

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

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

輸出結果如下,因為解釋器發出異常信號是IndexError,所以執行下標越界語句。

下標越界啦!
繼續運行...

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

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

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

string index out of range繼續運行...

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

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

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

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

下標越界啦!finally!
繼續運行...

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

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

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

finally!	#異常沒被捕獲,也執行了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…這種機制應該也不難理解了,因為省略了except 捕獲異常機制,所以異常不可能被處理,解釋器會將程序中斷,并將錯誤信息輸出,但finally語句塊的內容依然會被執行。例子代碼如下:

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

運行結果:

finally!	#異常沒被捕獲,也執行了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則繼續往下執行語句,如果是False則中斷程序,將錯誤信息輸出。

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

5、with…as處理機制

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

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

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

三、python異常自定義

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

1、異常自定義

??實際開發中,有時候系統提供的異常類型往往都不能滿足開發的需求。這時候就要使用到異常的自定義啦,你可以通過創建一個新的異常類來擁有自己的異常。自己定義的異常類繼承自 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__為構造函數,當我們創建對象時便會自動調用,__str__為對象說明信息函數,當使用print輸出對象的時候,只要自己定義了__str__方法,那么就會打印從在這個方法中return的數據。
??即print(MyException(0))時,便可打印“超時錯誤”這個字符串,print(MyException(1))時,便可打印“接收錯誤”這個字符串,心細的你應該可以理解,MyException(x)為臨時對象(x是傳入錯誤碼參數,這里只定義了0和1),與a = MyException(x),a為對象一個樣子 。 這里有一個好玩的說法,在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法。

2、異常拋出raise

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

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

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

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__部分返回的內容,即“接收錯誤”
        print(ex.error_num) 		# 輸出的是__init__中定義的error_num,即1demo_main()							#此處開始運行

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

四、異常使用注意事項

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

1、不要太依賴異常機制

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

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

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

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

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

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

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

以上是“Python中異常機制的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

和硕县| 武陟县| 武隆县| 泗阳县| 衡阳市| 蒙阴县| 清河县| 彩票| 大英县| 夏邑县| 朔州市| 嵩明县| 漳浦县| 克拉玛依市| 泸溪县| 房产| 丽水市| 城固县| 晋城| 宁波市| 石台县| 丁青县| 平定县| 大庆市| 清新县| 蒙阴县| 龙游县| 池州市| 太仆寺旗| 灵宝市| 绍兴县| 汤原县| 锦州市| 衢州市| 伽师县| 丹棱县| 泗洪县| 晋宁县| 松江区| 剑河县| 镇江市|