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