Определите с оператором, который автоматически включает попытки и исключения

Можно ли определить собственный оператор with, который автоматически включает попытку... кроме обработки ошибок? Например, было бы неплохо иметь сокращение для этого:

with Do_Something():
    try:
        ...
    except Exception as e:
        print(str(e))

... это выглядит так:

with Try_Something():
    ...
    

Как мы можем включить поведение try...except в следующий класс MWE?

class Do_Something():
    def __init__(self):
        pass

    def __enter__(self):
        print('Starting...')
        # invoke "try" somewhere here?
        return(self)

    def __exit__(self, except_type, except_value, tb):
        # invoke "except" somewhere here?

person Martin    schedule 14.05.2021    source источник
comment
Методы __exit__() позволяют обрабатывать исключения. Подробнее см. в документах.   -  person Klaus D.    schedule 15.05.2021
comment
Отвечает ли это на ваш вопрос? Обработка исключений внутри менеджеров контекста   -  person Corralien    schedule 15.05.2021
comment
@Corralien: ссылка была полезной, но она касается гораздо более конкретной проблемы. Это не полностью отвечает на вопрос, изложенный здесь, поскольку я не хочу обрабатывать ошибки определенным образом, я хочу воспроизвести вывод по умолчанию try...except. То есть вопрос сводится к тому, как вывести информацию о трассировке, предоставленную __exit__, аналогично тому, как это сделал бы str(e), используя аргумент, предоставленный except .   -  person Martin    schedule 15.05.2021


Ответы (2)


Согласно документам, если вы хотите подавить исключения, __exit__ должен вернуть True.

Аргументы, переданные в __exit__, будут описывать исключение на случай, если вы захотите принять условные решения.

person Lucas Ng    schedule 14.05.2021

Похоже, что with изначально поставляется с try под капотом и распространяет исключения в качестве аргументов для __exit__(...). Так что это может быть подходящим решением:

import traceback
class Try_Something():
    def __init__(self):
        pass

    def __enter__(self):
        print('Starting...')
        # invoke "try" somewhere here? -- No, "with" automatically invokes "try"
        return(self)

    def __exit__(self, except_type, except_value, tb):
        if not except_type:
            print('finished.')
        else:
            print('failed.')
            traceback.print_exc() # prints error similar to str(e) from the question
        return(True)

Я не нашел решения, которое идет без import traceback. Пожалуйста, прокомментируйте, есть ли способ напрямую распечатать информацию о трассировке, используя предоставленные аргументы без дополнительных модулей.

person Martin    schedule 14.05.2021