1. 程式人生 > >《python學習手冊》第34章 異常對象

《python學習手冊》第34章 異常對象

indexer app interrupt 類定義 ase num pac chan 捕捉

基於字符串的異常

python在2.6之前可以使用字符串來定義異常,並且是通過對象標識符來匹配的(即通過is 而不是==)

myexc = "My excetion string"
try:
    raise myexc
except myexc:
    print(caught)

基於類的異常

字符串定義的異常非常簡單,但是並不容易維護。使用類定義的異常通過超類關系進行匹配,只要except列舉出來的異常的類或者任何超類名,引發的異常都會匹配到。此外,類的異常還支持異常狀態信息,可以讓異常參與繼承層次。

類異常的例子

class General(Exception):pass
class Special1(General):pass class Special2(General):pass def raise0(): raise General() def raise1(): raise Special1() def raise2(): raise Special2() for fun in (raise0,raise1,raise2): try: fun() except General: import sys print(caught,sys.exc_info()[0])

運行的結果如下

caught <class
__main__.General> caught <class __main__.Special1> caught <class __main__.Special2>

將excep的部分化為下面的內容,結果一樣,sys.exc_info將在下一章講到。

    except General as x:
        print(caught:,x.__class__)

類異常的另一個例子

假如我們維護了一個mathlib.py的庫,原本定義了兩個異常Divzero和Oflow,

class Divzero(Exception): pass
class Oflow(Exception): pass def func(): raise Divzero()

當別人使用我們的庫的時候我們可以進行異常處理:

import mathlib
try:
    mathlib.func()
except (mathlib.Divzero,mathlib.Oflow):
    ‘‘‘do what you want to do ‘‘‘

但是,當我們維護我們的庫的時候新加入一個異常Uflow的時候,別人必須修改他們的代碼,這樣在大型程序當中非常的不好。所以我們嘗試把我們庫中的代碼寫成下面的形式:

class NumErr(Exception):pass
class Divzero(NumErr): pass
class Oflow(NumErr): pass
‘‘‘其余的異常‘‘‘
def func():
    raise Divzero()

別人引用的時候只需要寫成下面的形式即可:

import mathlib
try:
    mathlib.func()
except mathlib.NumErr:
    ‘‘‘do what you want to do ‘‘‘

無論我們增加多少個異常的類,別人的代碼都不需要進行修改。

內置Exception類

-BaseException類:異常的頂級根類,不可以被用戶定義的類直接繼承(應當使用Exception)。它提供了子類所繼承的默認的打印和狀態保持行為。

-Exception類:與應用相關的異常的頂層根超類,是BaseExcption的一個直接子類,並且是所有其他內置異常的超類,除了系統退出事件類以外(SystemExit、KeyboardInterrupt和GeneratorExit)。

In [2]: Exception.__bases__
Out[2]: (BaseException,)
In [3]: SystemExit.__bases__
Out[3]: (BaseException,)

-ArithmeticeError 所有數值錯誤的超類

In [4]: ArithmeticError.__bases__
Out[4]: (Exception,)

-OverflowError 識別特定的數值錯誤的子類

In [5]: OverflowError.__bases__
Out[5]: (ArithmeticError,)

從上面的代碼可以看出,python中的異常總是這樣的進行繼承的

默認打印和狀態

python內置異常提供默認的打印方法:傳遞給這些類的任何構造函數參數都會保存在實例的args元祖屬性中,並且當打印該實例的時候自動顯示。這就說明了為什麽傳遞給內置異常類的參數會出現在出錯消息中。

輸入:

raise IndexError

輸出:

Traceback (most recent call last):
  File "D:\application\eclipse\workspace\yichang\c3\t6.py", line 1, in <module>
    raise IndexError
IndexError

輸入:

raise IndexError(nihao)

輸出:

Traceback (most recent call last):
  File "D:\application\eclipse\workspace\yichang\c3\t6.py", line 1, in <module>
    raise IndexError(nihao)
IndexError: nihao

輸入:

i = IndexError(nihao)
print(i.args)

輸出:

(nihao,)

同樣,我們自己定義的類也是如此,因為他們繼承了內置超類中存在的構造很熟和顯示方法

輸入:

class MyErr(Exception):pass

try:
    raise MyErr(nihao)
except MyErr as x:
    print(x,x.args)

輸出:

nihao (nihao,)

輸入:

class MyErr(Exception):pass

try:
    raise MyErr(nihao,wohao,dajiahao)
except MyErr as x:
    print(x,x.args)

輸出:

(nihao, wohao, dajiahao) (nihao, wohao, dajiahao)

為什麽輸出x和x.args是一樣的?因為,這是由於__str__來決定的,直接輸出了str(args)。

定制我們自己的打印顯示:

其實,主要是修改我們定制的類中的__str__和__repr__方法,而__str__又是主要的。

下面我們為我們自己定義的類當中重定義__str__方法:

class MyErr(Exception):
    def __str__(self):
        return this is MYErr Exception

try:
    raise MyErr(nihao,wohao,dajiahao)
except MyErr as x:
    print(x)

輸出: this is MYErr Exception

改造構造方法

class FormatError(Exception):
    def __init__(self,line,file):
        self.line = line
        self.file = file

try:
    raise FormatError(2,nihao)
except FormatError as x:
    print(x.line,x.file)
    print(x.args[0],x.args[1])

通過改造構造方法,可以體統更多的細節,但是args還是可以使用的,輸出結果如下:

2 nihao
2 nihao

定義一些方法,在處理器內部執行

class FormatError(Exception):
    logfile = rlog.txt
    def __init__(self,line,file):
        self.line = line
        self.file = file
    def logger(self):
        log = open(self.logfile,a)
        print(error at line:,self.line,file:,self.file,file=log)

try:
    raise FormatError(11,t7.txt)
except FormatError as x:
    x.logger()

該異常定義了出錯的時候存入特定文件夾的功能,當捕獲異常的時候,執行logger方法

執行後在log.txt中有如下語句: error at line: 11 file: t7.txt


總結:這一章我們其實是明確了,異常主要是通過類來實現的,在try語句中,捕捉其超類就會捕捉這個類,以及類樹中超類下的所有子類。

《python學習手冊》第34章 異常對象