天天看點

python 異常

當你的程式中出現某些 異常的 狀況的時候,異常就發生了。例如,當你想要讀某個檔案的時候,而那個檔案不存在。或者在程式運作的時候,你不小心把它删除了。上述這些情況可以使用異常來處理。

假如你的程式中有一些無效的語句,會怎麼樣呢?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'      

輸出