Ответ 1
Правильная процедура заключается в том, чтобы поднять новое исключение внутри обработчика __exit__
.
Вы не должны поднимать исключение, которое было принято; для обеспечения цепочки контекстных менеджеров, в этом случае вам нужно просто вернуть значение false из обработчика. Однако ваши собственные исключения - это прекрасно.
Обратите внимание, что лучше использовать тест идентификации is
для проверки типа прошедшего исключения:
def __exit__(self, ex_type, ex_val, tb):
if ex_type is VagueThirdPartyError:
if ex_val.args[0] == 'foobar':
raise SpecificException('Foobarred!')
# Not raising a new exception, but surpressing the current one:
if ex_val.args[0] == 'eggs-and-ham':
# ignore this exception
return True
if ex_val.args[0] == 'baz':
# re-raise this exception
return False
# No else required, the function exits and `None` is returned
Вы также можете использовать issubclass(ex_type, VagueThirdPartyError)
, чтобы разрешать подклассы конкретного исключения.