當你的程式中出現某些 異常的 狀況的時候,異常就發生了。例如,當你想要讀某個檔案的時候,而那個檔案不存在。或者在程式運作的時候,你不小心把它删除了。上述這些情況可以使用異常來處理。
假如你的程式中有一些無效的語句,會怎麼樣呢?Python會引發并告訴你那裡有一個錯誤,進而處理這樣的情況。
錯誤
考慮一個簡單的
print
語句。假如我們把 print
誤拼為 Print
,注意大寫,這樣Python會 引發 一個文法錯誤。
>>> Print 'Hello World'
File "<stdin>", line 1
Print 'Hello World'
^
SyntaxError: invalid syntax
>>> print 'Hello World'
Hello World
我們可以觀察到有一個 SyntaxError
被引發,并且檢測到的錯誤位置也被列印了出來。這是這個錯誤的 錯誤處理器 所做的工作。 處理異常
我們可以使用
try..except
語句來處理異常。我們把通常的語句放在try-塊中,而把我們的錯誤處理語句放在except-塊中。
例13.1 處理異常
#!/usr/bin/python
# Filename: try_except.py
import sys
try:
s = raw_input('Enter something --> ')
except EOFError:
print '\nWhy did you do an EOF on me?'
sys.exit() # exit the program
except:
print '\nSome error/exception occurred.'
# here, we are not exiting the program
print 'Done'
輸出:
$ python try_except.py
Enter something -->
Why did you do an EOF on me?
Enter something --> Python is exceptional!
Done
它如何工作
我們把所有可能引發錯誤的語句放在
try
塊中,然後在
except
從句/塊中處理所有的錯誤和異常。
except
從句可以專門處理單一的錯誤或異常,或者一組包括在圓括号内的錯誤/異常。如果沒有給出錯誤或異常的名稱,它會處理 所有的 錯誤和異常。對于每個
try
從句,至少都有一個相關聯的
except
從句。
如果某個錯誤或異常沒有被處理,預設的Python處理器就會被調用。它會終止程式的運作,并且列印一個消息,我們已經看到了這樣的處理。
你還可以讓
try..catch
塊關聯上一個
else
從句。當沒有異常發生的時候,
else
從句将被執行。
我們還可以得到異常對象,進而擷取更多有個這個異常的資訊。這會在下一個例子中說明。
引發異常
你可以使用
raise
語句 引發 異常。你還得指明錯誤/異常的名稱和伴随異常 觸發的 異常對象。你可以引發的錯誤或異常應該分别是一個
Error
或
Exception
類的直接或間接導出類。
如何引發異常
例13.2 如何引發異常
#!/usr/bin/python
# Filename: raising.py
class ShortInputException(Exception):
'''A user-defined exception class.'''
def __init__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
try:
s = raw_input('Enter something --> ')
if len(s) < 3:
raise ShortInputException(len(s), 3)
# Other work can continue as usual here
except EOFError:
print '\nWhy did you do an EOF on me?'
except ShortInputException, x:
print 'ShortInputException: The input was of length %d, \
was expecting at least %d' % (x.length, x.atleast)
else:
print 'No exception was raised.'
$ python raising.py
Enter something -->
Why did you do an EOF on me?
$ python raising.py
Enter something --> ab
ShortInputException: The input was of length 2, was expecting at least 3
$ python raising.py
Enter something --> abc
No exception was raised.
這裡,我們建立了我們自己的異常類型,其實我們可以使用任何預定義的異常/錯誤。這個新的異常類型是
ShortInputException
類。它有兩個域——
length
是給定輸入的長度,
atleast
則是程式期望的最小長度。
在
except
從句中,我們提供了錯誤類和用來表示錯誤/異常對象的變量。這與函數調用中的形參和實參概念類似。在這個特别的
except
從句中,我們使用異常對象的
length
和
atleast
域來為使用者列印一個恰當的消息。
try..finally
假如你在讀一個檔案的時候,希望在無論異常發生與否的情況下都關閉檔案,該怎麼做呢?這可以使用
finally
塊來完成。注意,在一個
try
塊下,你可以同時使用
except
從句和
finally
塊。如果你要同時使用它們的話,需要把一個嵌入另外一個。
使用finally
例13.3 使用finally
#!/usr/bin/python
# Filename: finally.py
import time
try:
f = file('poem.txt')
while True: # our usual file-reading idiom
line = f.readline()
if len(line) == 0:
break
time.sleep(2)
print line,
finally:
f.close()
print 'Cleaning up...closed the file'