带有异常的类
我在看Python中的异常文档,感觉有点迷糊。链接在这里
我似乎找不到这段代码是怎么工作的。
class B:
pass
class C(B):
pass
class D(C):
pass
for c in [B, C, D]:
try:
raise c()
except D:
print "D"
except C:
print "C"
except B:
print "B"
输出是:
B
C
D
在这些类里,“pass”到底是干嘛的?我从文档中了解到,所有类的对象都被创建了(对象创建的顺序是:B、C和D),并且在它们的名字下会抛出异常。如果是这个顺序,那就能解释输出是B、C、D。
但是如果我们把except B
换成except D
,整个输出就变了。
class B:
pass
class C(B):
pass
class D(C):
pass
for c in [B, C, D]:
try:
raise c()
except B:
print "B"
except C:
print "C"
except D:
print "D"
输出是:
B
B
B
这让我有点晕:/
为什么“except”的顺序会改变输出呢?
我知道我在文档中漏掉了什么,可能是因为它不太清楚 :(
3 个回答
我觉得你写的异常处理语句的顺序很重要,因为Python会按照它看到的第一个符合条件的异常处理语句来执行。
在第一个例子中,输出的第一行会是B,因为类B并不是C或D的子类。在第二个例子中,所有的输出都会是B,因为每个类都是B的子类。
首先,程序会执行第一个匹配到的except
。所以,如果所有的对象都是B
的实例,而你在最前面写了except B:
,那么后面的其他except
就根本不会被考虑。
关键字pass
其实就是一个什么都不做的命令——它不执行任何操作。它的存在只是因为在Python中,代码是通过缩进来区分的,所以必须有一些内容。在Java或C++中,你会用{}
来表示空的函数或类体,而在Python中则用pass
。
因为 C
和 D
是 B
的子类,所以它们都能被 except B
这个部分捕捉到。当你处理异常时,记得要从最具体到最笼统地列出 except
的部分,因为你的异常会被第一个适用的部分捕捉到。
根据文档(我强调的部分):
except 部分指定一个或多个异常处理器。当在 try 部分没有发生异常时,不会执行任何异常处理器。当在 try 部分发生异常时,会开始寻找异常处理器。这个搜索会依次检查 except 部分,直到找到一个匹配异常的处理器。如果有不带表达式的 except 部分,它必须放在最后;因为它可以匹配任何异常。对于带有表达式的 except 部分,会先计算这个表达式,如果结果与异常“兼容”,那么这个部分就会匹配这个异常。一个对象与异常兼容的条件是,它是异常对象的类或基类,或者是一个包含与异常兼容的项的元组。
pass
语句用于需要一个语句但不需要其他内容的地方。class
语句不能有空的主体,但通常用文档字符串来代替会更好。
class B:
"""An exception that signals an error occurred"""
从语法上讲,文档字符串满足了 class
语句主体中需要一个语句的要求,同时也提供了额外的信息。