Давайте сначала разберемся с иерархией классов, включенной в этот пример кода
class B(Exception):
pass
class C(B):
pass
class D(C):
pass
B -> Базовый класс
C -> наследуется от B
D -> наследуетсяот C и C -> наследует от B
, таким образом, D -> наследует от B и C
В операторе try может быть больше одного, кроме предложения для разных исключений.Но будет выполнено не более одного предложения, кроме
Если вы не перехватили повышенное исключение, то базовому классу будет дан приоритет для перехвата.т.е. когда классы исключений наследуются, приоритет в except
отдается классу BASE (в вашем коде это класс B
).
Теперь первый случай:
for cls in [B, C, D]:
try:
raise cls()
except D:
print("D")
except C:
print("C")
except B:
print("B")
Iteration 1
: элемент: B
Первый элемент управления проверяет except D
, так как это не базовый класс и не соответствующий классна поднятый, тогда управление переместится на except C
и, наконец, выполнит except B
, таким образом печатая B
.
Iteration 2
: элемент: C
Первые контрольные проверкиexcept D
, поскольку это не базовый класс и не соответствующий классу с поднятым классом, тогда элемент управления переместится на except C
и выполнит except C
, таким образом печатая C
Iteration 3
: element:D
Первый элемент управления проверяет except D
как соответствующий класс, затем элемент управления выполняет except 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 B
в верхней части, кроме стека, элемент управления не переходит к последующим except C
и except D
.Таким образом, он выводит вывод как B
для каждой итерации цикла for.