带有异常的类

5 投票
3 回答
1196 浏览
提问于 2025-04-18 06:32

我在看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 个回答

0

我觉得你写的异常处理语句的顺序很重要,因为Python会按照它看到的第一个符合条件的异常处理语句来执行。

在第一个例子中,输出的第一行会是B,因为类B并不是C或D的子类。在第二个例子中,所有的输出都会是B,因为每个类都是B的子类。

1

首先,程序会执行第一个匹配到的except。所以,如果所有的对象都是B的实例,而你在最前面写了except B:,那么后面的其他except就根本不会被考虑。

关键字pass其实就是一个什么都不做的命令——它不执行任何操作。它的存在只是因为在Python中,代码是通过缩进来区分的,所以必须有一些内容。在Java或C++中,你会用{}来表示空的函数或类体,而在Python中则用pass

9

因为 CDB 的子类,所以它们都能被 except B 这个部分捕捉到。当你处理异常时,记得要从最具体到最笼统地列出 except 的部分,因为你的异常会被第一个适用的部分捕捉到。

根据文档(我强调的部分):

except 部分指定一个或多个异常处理器。当在 try 部分没有发生异常时,不会执行任何异常处理器。当在 try 部分发生异常时,会开始寻找异常处理器。这个搜索会依次检查 except 部分,直到找到一个匹配异常的处理器。如果有不带表达式的 except 部分,它必须放在最后;因为它可以匹配任何异常。对于带有表达式的 except 部分,会先计算这个表达式,如果结果与异常“兼容”,那么这个部分就会匹配这个异常。一个对象与异常兼容的条件是,它是异常对象的类或基类,或者是一个包含与异常兼容的项的元组。

pass 语句用于需要一个语句但不需要其他内容的地方。class 语句不能有空的主体,但通常用文档字符串来代替会更好。

class B:
    """An exception that signals an error occurred"""

从语法上讲,文档字符串满足了 class 语句主体中需要一个语句的要求,同时也提供了额外的信息。

撰写回答