2012-03-08 26 views
0

我正在從「絕對初學者的Python」一書中學習,並且學習了關於異常的章節。作者的解釋越來越短,並且對於這段代碼,我完全困惑,並且沒有任何解釋!有人可以一行一行解釋嗎?此代碼演示例外的功能是什麼?

#!/usr/bin/env python 
store = [] 
try: {}["foo"] 
except KeyError as e: store.append(e) 
try: 1/0 
except ZeroDivisionError as e: store.append(e) 
try: "".bar() 
except AttributeError as e: store.append(e) 
for exceptionobject in store: 
    ec = exceptionobject.__class__ 
    print(ec.__name__) 
    indent = " +-" 
    while ec.__bases__: 
     ec = ec.__bases__[0] 
     print(indent + ec.__name__) 
     indent = " " + indent 

回答

4
# create a list 
store = [] 

try: 
    # if something in this block would throw an exception, 
    # code could continue in a controlled way in an except block 

    # force a KeyError by looking up a non-existent key in an empty dictionary 
    {}["foo"] 

except KeyError as e: 
    # store the exception object in the list 
    store.append(e) 

# same scheme here; construct something that fails (1/0), 
# then instead of quitting the interpreter, continue operations 
try: 
    1/0 
except ZeroDivisionError as e: 
    store.append(e) 

# pythons exceptions hierarchy is diverse and exceptions carry meaningful 
# names expressing their context 
try: 
    # here we attept to lookup an attribute (that's happening technically 
    # before the call), which does not exists (because strings don't know 
    # how to bar... 
    "".bar() 

except AttributeError as e: 
    # ... and the the appropriate exception here is AttributeError 
    store.append(e) 

此時列表中有三個元素,它們是異常對象。

# loop over list 
for exceptionobject in store: 

    # get the class of the object via special method __class__ 
    # __class__ returns an object whose class is type actually; 
    # but don't be too confused by this 
    ec = exceptionobject.__class__ 

    # print the name of the exception class, now this is just a plain string 
    print(ec.__name__) 

    indent = " +-" 

    # use another special method __bases__ to get all superclasses 
    # of the exception class; all exceptions inherit from BaseException 
    # loop over the base classes 
    while ec.__bases__: 

     # get the first base class 
     ec = ec.__bases__[0] 

     # print its name an indent more 
     print(indent + ec.__name__) 
     indent = " " + indent 

結果應該是這個樣子:

KeyError 
+-LookupError 
    +-StandardError 
    +-Exception 
    +-BaseException 
    +-object 
ZeroDivisionError 
+-ArithmeticError 
    +-StandardError 
    +-Exception 
    +-BaseException 
    +-object 
AttributeError 
+-StandardError 
    +-Exception 
    +-BaseException 
    +-object 

顯示exception hierarchy的一部分。

4

上半年(具有三個except條款),它只是在關鍵字後力是很醒目(你趕上與except關鍵字例外)非常相同的異常,然後在異常處理程序(代碼;它在異常發生時運行,或者產生了)它將每個異常都添加到列表中。

在下半部分,它會遍歷保存的異常(現在列表中的異常)並顯示它們的一些屬性。

從這個練習中,你或許應該拿走主要是你如何捕捉異常,其次纔是一個事實,即一個例外是一個對象,就像一切都在Python:

In [6]: KeyError.__class__ 
Out[6]: type 

「類型」是類的類在Python中 - 這幾乎是一種語言的怪癖,如果你沒有得到這個,你不應該很快擔心它。無論如何,這一點表明一個例外是一個類。

In [7]: err = KeyError() 
In [8]: err.__class__ 
Out[8]: KeyError 

在這裏,我們實例化一個KeyError異常的對象,這是一件好事,當一個KeyError異常異常發生時,可自動發生(err在這種情況下是一樣的,在異常處理e在你的代碼)。正如你所看到的那樣,err的等級是KeyError