Python提供了兩個非常重要的功能來處理Python程序中的異常和錯誤,并在其中添加調(diào)試的函數(shù)功能 :
異常處理 : 在本教程中介紹。這是一個列表標(biāo)準(zhǔn)Python中提供的異常 : 標(biāo)準(zhǔn)異常。
斷言 : 在Python 3教程中的斷言中介紹。
標(biāo)準(zhǔn)異常
以下是Python中可用的標(biāo)準(zhǔn)異常列表 :
編號異常名稱描述
1Exception所有異常的基類
2StopIteration當(dāng)?shù)鞯膎ext()方法沒有指向任何對象時引發(fā)。
3SystemExit由sys.exit()函數(shù)引發(fā)。
4StandardError除StopIteration和SystemExit之外的所有內(nèi)置異常的基類。
5ArithmeticError數(shù)據(jù)計算出現(xiàn)的所有錯誤的基類。
6OverflowError當(dāng)計算超過數(shù)字類型的最大限制時引發(fā)。
7FloatingPointError當(dāng)浮點計算失敗時觸發(fā)。
8ZeroDivisonError對于所有的數(shù)字類型,當(dāng)對零進行除數(shù)或模數(shù)時產(chǎn)生。
9AssertionError在Assert語句失敗的情況下引發(fā)。
10AttributeError在屬性引用或分配失敗的情況下引發(fā)。
11EOFError當(dāng)沒有來自raw_input()或input()函數(shù)的輸入并且達到文件結(jié)尾時引發(fā)。
12ImportError導(dǎo)入語句失敗時引發(fā)。
13KeyboardInterrupt當(dāng)用戶中斷程序執(zhí)行時,通常按Ctrl + c。
14LookupError所有查找錯誤的基類。
15IndexError當(dāng)序列中沒有找到索引時引發(fā)。
16KeyError當(dāng)在字典中找不到指定的鍵時引發(fā)。
17NameError當(dāng)在本地或全局命名空間中找不到標(biāo)識符時引發(fā)。
18UnboundLocalError當(dāng)嘗試訪問函數(shù)或方法中的局部變量但未分配值時引發(fā)。
19EnvironmentError在Python環(huán)境之外發(fā)生的所有異常的基類。
20IOError在嘗試打開不存在的文件時,輸入/輸出操作失敗時觸發(fā),
例如print語句或open()函數(shù)。
21OSError引起操作系統(tǒng)相關(guān)的錯誤。
22SyntaxError當(dāng)Python語法有錯誤時引發(fā)。
23IndentationError當(dāng)縮進未正確指定時觸發(fā)。
24SystemError當(dāng)解釋器發(fā)現(xiàn)內(nèi)部問題時引發(fā),但遇到此錯誤時,
Python解釋器不會退出。
25SystemExit當(dāng)Python解釋器通過使用sys.exit()函數(shù)退出時引發(fā)。
如果沒有在代碼中處理,導(dǎo)致解釋器退出。
26TypeError在嘗試對指定數(shù)據(jù)類型無效的操作或函數(shù)時引發(fā)。
27ValueError當(dāng)數(shù)據(jù)類型的內(nèi)置函數(shù)具有有效參數(shù)類型時引發(fā),但參數(shù)具有指定的無效值。
28RuntimeError產(chǎn)生的錯誤不屬于任何類別時引發(fā)。
29NotImplementedError當(dāng)需要在繼承類中實現(xiàn)的抽象方法實際上沒有實現(xiàn)時引發(fā)。
Python中的斷言
斷言是一個健全檢查,可以在完成對程序的測試后打開或關(guān)閉。
試想斷言的最簡單的方法就是將它與一個raise:if語句(或者更準(zhǔn)確的說是一個加注if語句)相對應(yīng)。測試表達式,如果結(jié)果為false,則會引發(fā)異常。
斷言由版本1.5引入的assert語句來執(zhí)行,它是Python的最新關(guān)鍵字。
程序員經(jīng)常在函數(shù)開始時放置斷言來檢查有效的輸入,并在函數(shù)調(diào)用后檢查有效的輸出。
assert語句
當(dāng)它遇到一個assert語句時,Python會評估求值它的的表達式,是否為所希望的那樣。 如果表達式為false,Python會引發(fā)AssertionError異常。
assert的語法是 :
assert Expression[, Arguments]12復(fù)制代碼類型:[python] 如果斷言失敗,Python將使用ArgumentExpression作為AssertionError的參數(shù)。 使用try:except語句可以像任何其他異常一樣捕獲和處理AssertionError異常。 如果沒有處理,它們將終止程序并產(chǎn)生回溯。
示例
這里將實現(xiàn)一個功能:將給定的溫度從開爾文轉(zhuǎn)換為華氏度。如果是負(fù)溫度,該功能將退出 :
#!/usr/bin/python3def KelvinToFahrenheit(Temperature): assert (Temperature >= 0),"Colder than absolute zero!" return ((Temperature-273)*1.8)+32print (KelvinToFahrenheit(273))print (int(KelvinToFahrenheit(505.78)))print (KelvinToFahrenheit(-5))12345678910復(fù)制代碼類型:[python] 當(dāng)執(zhí)行上述代碼時,會產(chǎn)生以下結(jié)果 :
32.0451Traceback (most recent call last):File "test.py", line 9, in <module>print KelvinToFahrenheit(-5)File "test.py", line 4, in KelvinToFahrenheitassert (Temperature >= 0),"Colder than absolute zero!"AssertionError: Colder than absolute zero!123456789復(fù)制代碼類型:[python] 什么是異常?
一個例外是在程序執(zhí)行期間發(fā)生的一個事件,它破壞程序指令的正常流程。 一般來說,當(dāng)Python腳本遇到無法應(yīng)對的情況時,會引發(fā)異常。異常是一個表示錯誤的Python對象。
當(dāng)Python腳本引發(fā)異常時,它必須立即處理異常,否則終止并退出。
處理異常
如果有一些可能引發(fā)異常的可疑代碼,可以通過將可疑代碼放在try:塊中來保護您的程序。 在try:塊之后,包括一個except:語句,然后是一個盡可能優(yōu)雅地處理問題的代碼塊。
語法
下面是簡單的語法try .... except ... else塊 :
try: You do your operations here ......................except ExceptionI: If there is ExceptionI, then execute this block.except ExceptionII: If there is ExceptionII, then execute this block. ......................else: If there is no exception then execute this block.1234567891011復(fù)制代碼類型:[python] 以下是上述語法的幾個重點 :
一個try語句可以有多個except語句。 當(dāng)try塊包含可能引發(fā)不同類型的異常的語句時,這就很有用。
還可以提供一個通用的except子句,它處理任何異常。
在except子句之后,可以包含一個else子句。 如果try:block中的代碼不引發(fā)異常,則else塊中的代碼將執(zhí)行。
else:block是一個不需要try:block保護的代碼的地方。
示例
此示例打開一個文件,將內(nèi)容寫入文件,并且優(yōu)雅地出現(xiàn),因為完全沒有問題 :
#!/usr/bin/python3try: fh = open("testfile", "w") fh.write("This is my test file for exception handling!!")except IOError: print ("Error: can\'t find file or read data")else: print ("Written content in the file successfully") fh.close()12345678910復(fù)制代碼類型:[python] 這產(chǎn)生以下結(jié)果 :
Written content in the file successfully1復(fù)制代碼類型:[python] 示例
此示例嘗試打開一個沒有寫入權(quán)限的文件,因此它引發(fā)了一個異常 :
#!/usr/bin/python3try: fh = open("testfile", "r") fh.write("This is my test file for exception handling!!")except IOError: print ("Error: can\'t find file or read data")else: print ("Written content in the file successfully")1234567891011復(fù)制代碼類型:[python] 這產(chǎn)生以下結(jié)果 :
Error: can't find file or read data1復(fù)制代碼類型:[python] except子句沒有指定異常
也可以使用except語句,但不定義異常,如下所示 :
try: You do your operations here ......................except: If there is any exception, then execute this block. ......................else: If there is no exception then execute this block.123456789復(fù)制代碼類型:[python] 這種try:except語句捕獲所有發(fā)生的異常。使用這種try:except語句不被認(rèn)為是一個很好的編程實踐,因為它捕獲所有異常,但不會讓程序員能更好地識別發(fā)生的問題的根本原因。
except子句指定多個異常
還可以使用相同的except語句來處理多個異常,如下所示:
try: You do your operations here ......................except(Exception1[, Exception2[,...ExceptionN]]]): If there is any exception from the given exception list, then execute this block. ......................else: If there is no exception then execute this block.12345678910復(fù)制代碼類型:[python] try:finally子句
可以使用finally:塊和try:塊。 finally:塊是放置必須執(zhí)行代碼的地方,無論try塊是否引發(fā)異常。 try:finally語句的語法是這樣的 :
try: You do your operations here; ...................... Due to any exception, this may be skipped.finally: This would always be executed. ......................1234567復(fù)制代碼類型:[python] 注意 : 可以提供except子句或finally子句,但不能同時提供。不能使用else子句以及finally子句。
示例
#!/usr/bin/python3try: fh = open("testfile", "w") fh.write("This is my test file for exception handling!!")finally: print ("Error: can\'t find file or read data") fh.close()12345678復(fù)制代碼類型:[python] 如果沒有以寫入形式打開文件的權(quán)限,則會產(chǎn)生以下結(jié)果 :
Error: can't find file or read data1復(fù)制代碼類型:[python] 同樣的例子可以寫得更干凈如下 :
#!/usr/bin/python3try: fh = open("testfile", "w") try: fh.write("This is my test file for exception handling!!") finally: print ("Going to close the file") fh.close()except IOError: print ("Error: can\'t find file or read data")123456789101112復(fù)制代碼類型:[python] 當(dāng)try塊中拋出異常時,執(zhí)行將立即傳遞給finally塊。 在finally塊中的所有語句都被執(zhí)行之后,異常被再次引發(fā),如果存在于try:except語句的下一個更高的層中,則在except語句中處理異常。
異常參數(shù)
一個異??梢杂幸粋€參數(shù),參數(shù)它是一個值,它提供有關(guān)該問題的其他信息。 參數(shù)的內(nèi)容因異常而異。 可以通過在except子句中提供變量來捕獲異常的參數(shù),如下所示:
try: You do your operations here ......................except ExceptionType as Argument: You can print value of Argument here...12345復(fù)制代碼類型:[python] 如果編寫代碼來處理單個異常,則可以在except語句中使用一個變量后跟異常的名稱。 如果要捕獲多個異常,可以使用一個變量后跟隨異常的元組。
此變量接收大部分包含異常原因的異常值。 變量可以以元組的形式接收單個值或多個值。 該元組通常包含錯誤字符串,錯誤編號和錯誤位置。
示例
以下是一個例外 :
#!/usr/bin/python3# Define a function here.def temp_convert(var): try: return int(var) except ValueError as Argument: print ("The argument does not contain numbers\n", Argument)# Call above function here.temp_convert("xyz")1234567891011復(fù)制代碼類型:[python] 這產(chǎn)生以下結(jié)果 :
The argument does not contain numbersinvalid literal for int() with base 10: 'xyz'123復(fù)制代碼類型:[python] 拋出異常
可以通過使用raise語句以多種方式引發(fā)異常。raise語句的一般語法如下 :
語法
raise [Exception [, args [, traceback]]]12復(fù)制代碼類型:[python] 這里,Exception是異常的類型(例如,NameError),args是異常參數(shù)的值。 參數(shù)是可選的; 如果沒有提供,則異常參數(shù)為None。
最后一個參數(shù)traceback也是可選的(在實踐中很少使用),如果存在,則是用于異常的追溯對象。
示例
異??梢允亲址?,類或?qū)ο蟆?Python核心引發(fā)的大多數(shù)異常都是類,一個參數(shù)是類的一個實例。 定義新的例外是非常容易的,可以做到如下 :
def functionName( level ): if level <1: raise Exception(level) # The code below to this would not be executed # if we raise the exception return level123456復(fù)制代碼類型:[python] 注意 : 為了捕獲異常,“except”子句必須引用與類對象或簡單字符串相同的異常。例如,為了捕獲上述異常,必須寫出except子句如下:
try: Business Logic here...except Exception as e: Exception handling here using e.args...else: Rest of the code here...1234567復(fù)制代碼類型:[python] 以下示例說明了使用引發(fā)異常 :
#!/usr/bin/python3def functionName( level ): if level <1: raise Exception(level) # The code below to this would not be executed # if we raise the exception return leveltry: l = functionName(-10) print ("level = ",l)except Exception as e: print ("error in level argument",e.args[0])123456789101112131415復(fù)制代碼類型:[python] 這將產(chǎn)生以下結(jié)果 :
error in level argument -101復(fù)制代碼類型:[python] 用戶定義的異常
Python還允許通過從標(biāo)準(zhǔn)內(nèi)置異常導(dǎo)出類來創(chuàng)建自己的異常。
這是一個與RuntimeError有關(guān)的示例。 在這里,從RuntimeError類創(chuàng)建一個子類。 當(dāng)需要在捕獲異常時顯示更多具體信息時,這就很有用了。
在try塊中,用戶定義的異常被引發(fā)并被捕獲在except塊中。 變量e用于創(chuàng)建Networkerror類的實例。
class Networkerror(RuntimeError): def __init__(self, arg): self.args = arg123復(fù)制代碼類型:[python] 所以當(dāng)定義了上面的類以后,就可以使用以下命令拋出異常 :
try: raise Networkerror("Bad hostname")except Networkerror,e: print e.args