我正在浏览python异常的文档:-(https://docs.python.org/2/tutorial/classes.html#exceptions-are-classes-too)
我似乎不明白这段代码是如何工作的
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 D
代替excpet B
,整个输出就会改变。
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"的顺序如何改变输出?
我知道我从文档中遗漏了一些东西,也许是因为它不是很清楚:(
由于C
和D
是B
的子类,它们都被except B
子句捕获。当捕获异常时,您需要始终列出except
子句,从最具体到最不具体,因为您的异常被第一个应用的捕获。
来自文档(强调我的):
except子句指定一个或多个异常处理程序。当try子句中没有出现异常时,就不会执行异常处理程序。当try套件中出现异常时,将开始搜索异常处理程序。这个搜索依次检查except子句,直到找到一个匹配异常的子句。一个无表达式的except子句,如果存在,必须在最后;它匹配任何异常。对于带有表达式的except子句,将对该表达式求值,如果结果对象与异常"兼容",则该子句与异常匹配。如果对象是异常对象的类或基类,或者是包含与异常兼容的项的元组,则该对象与异常兼容。
pass
语句用于期望语句,但不需要其他语句的地方。class
语句不能有空体,但通常使用docstring更好。
class B:
"""An exception that signals an error occurred"""
从语法上讲,docstring满足了class
语句体中对语句的需求,但也提供了额外的信息。
第一个匹配的except
是执行的。因此,如果所有对象都是B
的实例,并且您将except B:
放在首位,那么其他except
甚至不会被考虑。
关键字pass
只是一个无操作命令——它什么也不做。它的存在只是因为Python源代码是基于缩进的。在Java或c++中,您可以将空函数/类主体写为{}
,在Python中它是pass
。
在我看来,except语句的顺序很重要,因为Python将遵循它看到的第一个为真except语句的异常逻辑。
在第一个示例中,第一行输出将是B,因为类B不是C或d的子类。在第二个示例中,所有输出将是B,因为每个类都是B的子类。