Почему исключения исчезают, если я возвращаю self в методе __exit__? - PullRequest
0 голосов
/ 26 мая 2020

Я столкнулся с интересным явлением в Python 3.6. Если я возвращаю self в методе __exit__ класса, кажется, что любое исключение, возникшее в блоке with, который использует указанный класс, просто исчезает. Я не знаю, почему это происходит, и это не кажется желательным поведением. С помощью следующего кода я могу воспроизвести это:

class SomeObject(object):
    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        return self


if __name__ == '__main__':
    with SomeObject():
        print('This print statement works')
        raise Exception('This exception is not raised for some reason')
    print('This statement is printed as if nothing happened')

Это приводит меня к следующим вопросам:

  • Можете ли вы воспроизвести это или это только я?
  • Предполагается, что исключение исчезнет (т.е. есть ли на то веская причина)? И если да, то почему?

Ответы [ 2 ]

5 голосов
/ 26 мая 2020

Способ, которым __exit__ решает, вызывать ли исключение, основан на «истинности» возвращаемого значения. Поскольку экземпляр класса будет оценивать как True в логической операции; ошибка не возникает. Если возвращаемое значение оценивается как False, возникает ошибка.

4 голосов
/ 26 мая 2020

Вот документ .

Выйти из контекста выполнения, связанного с этим объектом. Параметры описывают исключение, которое привело к выходу из контекста. Если из контекста был завершен выход без исключения, все три аргумента будут равны Нет.

Если предоставлено исключение, и метод желает подавить исключение (т. Е. Предотвратить его распространение), он должен вернуть истинное значение. В противном случае исключение будет обработано нормально после выхода из этого метода.

Обратите внимание, что методы exit () не должны повторно вызывать переданное исключение; это ответственность вызывающего.

Как мы видим, если вы хотите подавить исключение, вы можете вернуть истинное значение. Пока объект оценивается как True. Итак, ваше исключение подавлено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...