Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用类在python中进行异常处理_Python_Python 3.x_Exception Handling - Fatal编程技术网

使用类在python中进行异常处理

使用类在python中进行异常处理,python,python-3.x,exception-handling,Python,Python 3.x,Exception Handling,我对python例外情况表示怀疑。 下面的代码取自python文档,有一点我很困惑。如果有人能帮忙,我会很感激的。 此处,该代码给出如下输出: B、C、D 如果我更改除以下代码以外的部分代码: 输出将是: B B B 当我不使用try块运行此代码时,如下所示: class B(Exception): pass class C(B): pass class D(C): pass for cls in [B, C, D]: raise cls() 这里的输出是: T

我对python例外情况表示怀疑。 下面的代码取自python文档,有一点我很困惑。如果有人能帮忙,我会很感激的。 此处,该代码给出如下输出:

B、C、D

如果我更改除以下代码以外的部分代码: 输出将是:

B B B

当我不使用try块运行此代码时,如下所示:

class B(Exception):
    pass
class C(B):
    pass
class D(C):
    pass
for cls in [B, C, D]:
    raise cls()
这里的输出是:

Traceback (most recent call last):
  File "C:/Users/885710/Documents/PY/ErrorHandling.py", line 12, in <module>
    raise cls()
B
输出是这个吗

Traceback (most recent call last):
  File "C:/Users/885710/Documents/PY/ErrorHandling.py", line 12, in <module>
    raise cls()
C

即使为所有3个B、C、D类定义了except,因为
B
C
D
的超类,您的第二个版本将始终为
B
使用第一个
except
块。因为Python运行时将从上到下搜索匹配的
,除了
块。如果异常是
except
块中类的实例,则
except
块匹配。例如,如果抛出一个实例
C
,该块将匹配,因为
C()
也是
B
的实例

根据经验法则,
except
语句必须从最具体的条件减少到最一般的条件,例如。g、 :

try:
    throw ...
except D: # the most specific class
    print("D")
except C: # is more specific than B but less than D
    print("C")
except B: # the most general class in your hierarchy
    print("B")
except BaseException as e: the most general exception class
    print(e.__class__.__name__)
说:

except子句中的类与异常(如果是)兼容 同一类还是基类

因此,给定代码:

for cls in [B, C, D]:
    try:
        raise cls()
    except D:
        print("D")
    except C:
        print("C")
    except B:
        print("B")
可简化为以下内容:

for cls in [B, C, D]:
    foo = cls()
    if isinstance(foo, D):
        print("D")
    elif isinstance(foo, C):
        print("C")
    elif isinstance(foo, B):
        print("B")
然后,您的修改将变成:

for cls in [B, C, D]:
    foo = cls()
    if isinstance(foo, B):
        print("B")
    elif isinstance(foo, C):
        print("C")
    elif isinstance(foo, D):
        print("D")

因此,无论
foo
B
C
还是
D
的实例,它都将满足第一种情况,因为
isinstance
也会为子类的实例生成
True

<

class B(Exception):
    pass
class C(B):
    pass
class D(C):
    pass
B->基类

C->从B继承

D->从C和C继承->从B继承

因此,D->继承自B和C

对于不同的异常,try语句可能有多个except子句。但最多只执行一个例外条款

除非捕获引发的异常,否则基类将被赋予捕获的优先级。i、 e当继承异常类时,
except
中的优先级被赋予基类(在代码中是类
B

第一个案例:

for cls in [B, C, D]:
    try:
        raise cls()
    except D:
        print("D")
    except C:
        print("C")
    except B:
        print("B")
迭代1
: 要素:B

首先控件检查
除了D
,因为它不是基类,也不是与提升的类匹配的类,然后控件将移动到
除了C
,最后它将执行
除了B
,从而打印
B

迭代2
: 元素:C

首先控件检查
除了D
,因为它不是基类,也不是与提升的类匹配的类,然后控件将移动到
除了C
,并将执行
除了C
,从而打印
C

迭代3
: 元素:D

首先控件检查
,除了D
,因为它是一个匹配的类,然后控件将 执行除D之外的
,从而打印
D

现在考虑第二种情况:

for cls in [B, C, D]:
    try:
        raise cls()
    except B:
        print("B")
    except C:
        print("C")
    except D:
        print("D")

这里
B
是类
C
D
的基类,因此当您在except堆栈的顶部写入
except B
时,控件不会转到后续的
except C
except D
。因此,对于for循环的每次迭代,它都将输出打印为
B

C是B,D是C(依次是B),因此(传递地)D是B(这就是继承的全部内容)。您尝试处理异常的顺序很重要(在本例中)。也许您应该从Exception扩展所有类(而不是像现在这样从一个类扩展到另一个类),这样您就可以在第二个代码片段中获得所需的行为(而不改变其他场景)<代码>C类(异常):
D类(异常):
。也许你应该从异常扩展所有的类>>你能用例子解释一下吗?如果D是C,C是B,因此D是B,那么为什么它在第一个代码段中打印B,C,D,在第二个代码段中打印B,B,B。仍然没有得到重点,因为is只是一种方式:C是B,但B不是C。好的,谢谢你。。明白了,好极了!非常感谢你的解释。谢谢你再加上一个解释。帮了大忙!
for cls in [B, C, D]:
    foo = cls()
    if isinstance(foo, B):
        print("B")
    elif isinstance(foo, C):
        print("C")
    elif isinstance(foo, D):
        print("D")
class B(Exception):
    pass
class C(B):
    pass
class D(C):
    pass
for cls in [B, C, D]:
    try:
        raise cls()
    except D:
        print("D")
    except C:
        print("C")
    except B:
        print("B")
for cls in [B, C, D]:
    try:
        raise cls()
    except B:
        print("B")
    except C:
        print("C")
    except D:
        print("D")