1. 程式人生 > >Python 2.7 錯誤與異常

Python 2.7 錯誤與異常

1 語法錯誤

產生語法錯誤時,解析器會重複錯誤的行,並且使用一個箭頭指向錯誤行中最早發現錯誤的位置。錯誤便是由箭頭之前的符號引發的(至少是在此處檢測到的)。檔名與行數將會被打印出來,當輸入來自指令碼時用以得知在哪裡找尋錯誤。

2 異常

在執行期間檢測到的錯誤稱之為異常,它們通常不會無條件失敗。 大多數異常並不是由程式處理並輸出錯誤資訊,這些異常稱為內建異常,例如,除零引發的ZeroDivisionError。

異常有著不同的型別,異常型別將會作為異常資訊的一部分輸出。 作為異常型別列印的字串實際上是被引發的內建異常的名稱。 這一點對於所有的內建異常都適用,但是對於使用者自定義的異常並不是一定可行(即使這是非常有用的慣例)。 標準異常名稱是內建識別符號,並不是保留關鍵字。

錯誤資訊的剩餘部分是每個錯誤型別以及造成的原因的詳盡描述。

錯誤資訊的前一部分以堆疊形式顯示了異常發生的上下文。它通常包括列出堆疊回溯的源行數,但是,它不會顯式從標準輸入讀取的行數。

3 處理異常

while True:
    try:
        x = int(raw_input("Enter a number: "))
        break
    except ValueError:
        print "Try again..."

note:在輸入整數型別的值之前,不斷提示輸入。

try語句處理過程:

  • 首先,try子句(try與except關鍵字之間的語句)將會執行。
  • 如果沒有異常發生,except子句將會被跳過並且辦成try語句的執行。
  • 如果在執行try子句的過程中發生了異常,try子句的剩餘部分將會被跳過。接著,如果異常型別匹配except關鍵字之後的異常名,except子句將被執行,然後執行try子句之後的語句。
  • 如果一個異常發生,但是except之後的異常名稱沒有匹配發生的異常,該異常將會被傳遞給外層try語句,如果始終沒有找到異常的處理程式,執行將會被終止,輸出錯誤資訊。

一個try語句可以有多個except子句,用來指定不同型別異常的處理程式。至多隻有一個處理程式被執行。 處理程式只會處理髮生在對應try語句中的異常,不會處理同一try語句的其他對應處理程式中發生的異常。

# except子句可以使用由多個異常組成的元組
try :
    pass
except (RuntimeError, TypeError, NameError):
    pass
import sys
try:
    f = open('ttt')
    s = f.readline()
    i = int(s.strip())
    print i
except IOError as e:
    print e.args
    print e.errno, e.strerror
except ValueError:
    print 'convert failure'
except:
    print 'Unexcepted error:', sys.exc_info()[0]
    raise
else:
    print "success"

note:except不帶異常,會捕獲所有的異常。 note:else子句將會在try子句不丟擲異常的情況下執行。 note:except xxx as xx:用於為異常指定繫結的變數,異常例項的引數儲存在異常的args屬性中。

如果異常有引數,引數將會作為未處理的異常的最後一部分資訊打印出來。

# 處理try呼叫的函式引發的異常
def this_falis():
    x = 1/0
try:
    this_falis()
except ZeroDivisionError as detail:
    print detail

4 提出異常

# 手動提出異常
raise NameError("sdfs")

# except再丟擲異常
try:
    raise NameError('aaaa')
except NameError:
    print "except"
    raise

5 使用者自定義異常

# 定義異常MyError,使用value屬性替換args屬性
class MyError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

當建立一個可能提出多個不同異常的模組時,常見的操作是在模組中建立建一個異常基類,然後針對不同的錯誤狀況建立特定的異常子類。 大多數的異常一般以“Error”為結尾命名,類似標準異常的命名。 許多標準模組定義了自己的異常,用於輸出在自己定義的函式中可能發生的錯誤。

6 定義清理行為

使用finally子句定義清理行為,無論在什麼情況下,清理行為都必須執行。

# 定義清理行為
try:
    raise KeyboardInterrupt
finally:
    print '!!!!'

在離開try語句之前,無論異常是否發生,finally子句總會執行。當try子句中產生了異常並且此異常沒有對應的except子句(或是異常產生於except或else子句中),在finally子句執行之後,此異常才會被再丟擲。當try子句中的語句通過break、continue或return語句離開了try子句,此時finally子句會在離開程式的位置執行。

實際應用程式中,finally一般用於釋放外部資源(例如檔案或網路連線),這樣無論資源的使用是否正常執行,都可以完成資源釋放。

7 預定義清理行為

一些物件定義了不需要此物件時的標準清理行為,無論使用物件的操作是否執行成功。

with open("sss") as f:
    for line in f:
        print line