Как я могу поймать исключение внутри контекстного менеджера? - PullRequest
1 голос
/ 20 марта 2020

У меня есть случай, когда мне нужно поймать какое-то исключение ( в коде, например, я хочу поймать ZeroDivisionError) и обработать его в моем собственном диспетчере контекста. Мне нужно проверить счетчик этого исключения и сделать печать в консоли. Теперь, когда я запускаю свой код, я получаю ZeroDivisionError один раз, а затем

Traceback (most recent call last):
  File "/home/example.py", line 23, in foo
    a / b
ZeroDivisionError: division by zero

Process finished with exit code 1

Например:

class ExceptionCather:
    def __init__(
            self,
            try_counter,
            exc_type=None
    ):
        self.try_counter = try_counter

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc, tb):
        if exc_type == ZeroDivisionError:
            self.try_counter += 1
            if self.try_counter == 2:
                print(self.try_counter)


def foo(a, b):
    try_counter = 0
    while True:
        with ExceptionCather(try_counter):
            a / b


if __name__ == '__main__':
    foo(1, 0)

Как я могу поймать ошибку, сделать печать в утешить и продолжить с моим сценарием? Будем благодарны за помощь

1 Ответ

1 голос
/ 29 апреля 2020

Я не уверен, чего вы хотите достичь, но если вы хотите обработать ZeroDivisionError, просто верните True из __exit__:

class ExceptionCather:
    def __init__(
            self,
            try_counter,
            exc_type=None
    ):
        self.try_counter = try_counter

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc, tb):
        if exc_type == ZeroDivisionError:
            self.try_counter += 1
            if self.try_counter == 2:
                print(self.try_counter)
            return True  # This will not raise `ZeroDivisonError`


def foo(a, b):
    try_counter = 0
    while True:
        with ExceptionCather(try_counter):
            a / b


if __name__ == '__main__':
    foo(1, 0)

Обратите внимание, потому что вы находитесь в то время как l oop, когда вы нажимаете Ctrl + C, чтобы остановить l oop, KeyboardInterrupt повышается, что поднимает ZeroDivisonError от вашего ExceptionCatcher (так как __exit__ не вернул True в конце).

...