2012-03-08 25 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