Python提供了兩個非常重要的功能來處理Python程式中的異常和錯誤,並在其中新增偵錯的函式功能 -
以下是Python中可用的標準異常列表 -
編號 | 異常名稱 | 描述 |
---|---|---|
1 | Exception | 所有異常的基礎類別 |
2 | StopIteration | 當迭代器的next() 方法沒有指向任何物件時引發。 |
3 | SystemExit | 由sys.exit() 函式引發。 |
4 | StandardError | 除StopIteration 和SystemExit 之外的所有內建異常的基礎類別。 |
5 | ArithmeticError | 資料計算出現的所有錯誤的基礎類別。 |
6 | OverflowError | 當計算超過數位型別的最大限制時引發。 |
7 | FloatingPointError | 當浮點計算失敗時觸發。 |
8 | ZeroDivisonError | 對於所有的數位型別,當對零進行除數或模數時產生。 |
9 | AssertionError | 在Assert 語句失敗的情況下引發。 |
10 | AttributeError | 在屬性參照或分配失敗的情況下引發。 |
11 | EOFError | 當沒有來自raw_input() 或input() 函式的輸入並且達到檔案結尾時引發。 |
12 | ImportError | 匯入語句失敗時引發。 |
13 | KeyboardInterrupt | 當使用者中斷程式執行時,通常按Ctrl + c 。 |
14 | LookupError | 所有查詢錯誤的基礎類別。 |
15 | IndexError | 當序列中沒有找到索引時引發。 |
16 | KeyError | 當在字典中找不到指定的鍵時引發。 |
17 | NameError | 當在本地或全域性名稱空間中找不到識別符號時引發。 |
18 | UnboundLocalError | 當嘗試存取函式或方法中的區域性變數但未分配值時引發。 |
19 | EnvironmentError | 在Python環境之外發生的所有異常的基礎類別。 |
20 | IOError | 在嘗試開啟不存在的檔案時,輸入/輸出操作失敗時觸發,例如print 語句或open() 函式。 |
21 | OSError | 引起作業系統相關的錯誤。 |
22 | SyntaxError | 當Python語法有錯誤時引發。 |
23 | IndentationError | 當縮排未正確指定時觸發。 |
24 | SystemError | 當直譯器發現內部問題時引發,但遇到此錯誤時,Python直譯器不會退出。 |
25 | SystemExit | 當Python直譯器通過使用sys.exit() 函式退出時引發。 如果沒有在程式碼中處理,導致直譯器退出。 |
26 | TypeError | 在嘗試對指定資料型別無效的操作或函式時引發。 |
27 | ValueError | 當資料型別的內建函式具有有效引數型別時引發,但引數具有指定的無效值。 |
28 | RuntimeError | 產生的錯誤不屬於任何類別時引發。 |
29 | NotImplementedError | 當需要在繼承類中實現的抽象方法實際上沒有實現時引發。 |
斷言是一個健全檢查,可以在完成對程式的測試後開啟或關閉。
試想斷言的最簡單的方法就是將它與一個raise-if
語句(或者更準確的說是一個加註if
語句)相對應。測試表示式,如果結果為false
,則會引發異常。
斷言由版本1.5
引入的assert
語句來執行,它是Python的最新關鍵字。
當它遇到一個assert
語句時,Python會評估求值它的的表示式,是否為所希望的那樣。 如果表示式為false
,Python會引發AssertionError
異常。
assert
的語法是 -
assert Expression[, Arguments]
如果斷言失敗,Python將使用ArgumentExpression
作為AssertionError
的引數。 使用try-except
語句可以像任何其他異常一樣捕獲和處理AssertionError
異常。 如果沒有處理,它們將終止程式並產生回溯。
範例
這裡將實現一個功能:將給定的溫度從開爾文轉換為華氏度。如果是負溫度,該功能將退出 -
#!/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))
當執行上述程式碼時,會產生以下結果 -
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!
一個例外是在程式執行期間發生的一個事件,它破壞程式指令的正常流程。 一般來說,當Python指令碼遇到無法應對的情況時,會引發異常。異常是一個表示錯誤的Python物件。
當Python指令碼引發異常時,它必須立即處理異常,否則終止並退出。
如果有一些可能引發異常的可疑程式碼,可以通過將可疑程式碼放在try:
塊中來保護您的程式。 在try:
塊之後,包括一個except:
語句,然後是一個儘可能優雅地處理問題的程式碼塊。
語法
下面是簡單的語法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
塊包含可能引發不同型別的異常的語句時,這就很有用。except
子句,它處理任何異常。except
子句之後,可以包含一個else
子句。 如果try:block
中的程式碼不引發異常,則else
塊中的程式碼將執行。else-block
是一個不需要try:block
保護的程式碼的地方。範例
此範例開啟一個檔案,將內容寫入檔案,並且優雅地出現,因為完全沒有問題 -
#!/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()
這產生以下結果 -
Written content in the file successfully
範例
此範例嘗試開啟一個沒有寫入許可權的檔案,因此它引發了一個異常 -
#!/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")
這產生以下結果 -
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
語句捕獲所有發生的異常。使用這種try-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.
可以使用finally:
塊和try:
塊。 finally:
塊是放置必須執行程式碼的地方,無論try
塊是否引發異常。 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()
如果沒有以寫入形式開啟檔案的許可權,則會產生以下結果 -
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
塊中丟擲異常時,執行將立即傳遞給finally
塊。 在finally
塊中的所有語句都被執行之後,異常被再次引發,如果存在於try-except
語句的下一個更高的層中,則在except
語句中處理異常。
一個異常可以有一個引數,引數它是一個值,它提供有關該問題的其他資訊。 引數的內容因異常而異。 可以通過在except
子句中提供變數來捕獲異常的引數,如下所示:
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")
這產生以下結果 -
The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'
可以通過使用raise
語句以多種方式引發異常。raise
語句的一般語法如下 -
語法
raise [Exception [, args [, traceback]]]
這裡,Exception
是異常的型別(例如,NameError
),args
是異常引數的值。 引數是可選的; 如果沒有提供,則異常引數為None
。
最後一個引數traceback
也是可選的(在實踐中很少使用),如果存在,則是用於異常的追溯物件。
範例
異常可以是字串,類或物件。 Python核心引發的大多數異常都是類,一個引數是類的一個範例。 定義新的例外是非常容易的,可以做到如下 -
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...
以下範例說明了使用引發異常 -
#!/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])
這將產生以下結果 -
error in level argument -10
Python還允許通過從標準內建異常匯出類來建立自己的異常。
這是一個與RuntimeError
有關的範例。 在這裡,從RuntimeError
類建立一個子類。 當需要在捕獲異常時顯示更多具體資訊時,這就很有用了。
在try
塊中,使用者定義的異常被引發併被捕獲在except
塊中。 變數e
用於建立Networkerror
類的範例。
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
所以當定義了上面的類以後,就可以使用以下命令丟擲異常 -
try:
raise Networkerror("Bad hostname")
except Networkerror,e:
print e.args