下面是python文档中处理异常处理和类的一段示例代码。我正在努力理解这两者,而且我的背景是Java,所以我习惯于强类型的类和变量。有人能详细解释一下这里发生了什么吗?
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的实例,还是只是在创建一个类类型。如果它们只是类类型,我假设它们是在for c in [B, C, D]:
中安装的。如何在没有参数的情况下实例化类C和类D的实例?那么这些异常的东西是怎么回事呢?
前六行创建类。我喜欢将它们视为稍后将创建的实例的定义。使用for c in [B, C, D]:
不会实例化任何东西;它只是将c
分配给仍然只是类的B
、C
和D
中的每一个。对于第一次迭代,c
与B
是相同的。因此,当您说raise c()
时,c()
会生成B
的实例,并将其作为异常引发。该异常在except B:
块中被捕获,并导致print "B"
行执行。对于下一次迭代,c
被分配给[B, C, D]
中的下一个值:C
。现在,raise c()
生成C
的一个实例,并将其作为异常进行引发。该异常在except C:
块中被捕获,并且print "C"
行被执行。D
也发生了同样的情况。
前六行定义了类。它们是在没有参数的情况下实例化的,因为例如class C(B):
意味着类C
从B
继承,而不是C
的实例化需要传递参数。这在关于类的文档中有解释。
每次通过循环,解释器都会引发给定类的错误。它将打印引发的任何类型的异常类,B
代表B
,依此类推。当您运行该代码时,输出是B
,然后是C
,再是D
,因为这些都是按顺序引发的异常类别,正如您在循环迭代的[B, C, D]
中看到的那样。
前六行用于创建类类型。
由于python中的所有内容都可以分配给一个变量,这包括for c in [B, C, D]:
正在执行的函数、类(而不仅仅是该类的实例化对象)。
最后,异常首先在try:
中做什么,它试图通过创建一个c
类型的异常来引发它的实例。因此,它首先引发一个B类型的异常,然后是C类型,然后是D类型。
except
用于捕获每种类型的异常。在python 2中,任何对象都可以作为异常引发,这与python 3不同,在python 3中,所有引发的异常都必须派生自BaseException 类型