Pull to refresh

Comments 7

В питоне 3.3 есть довольно похожая штука, ExitStack называется.

Пример из статьи примерно так можно записать:

from contextlib import ExitStack

with ExitStack() as stack:
    f = stack.enter_context(open('file.txt', 'w))  # <- интеграция с другими контекст-менеджерами
    stack.callback(print, "Defer called")  # <- обычный коллбэк
    
    @stack.callback   # <- так тоже можно добавить коллбэк
    def my_defer():
        recover()
        
    print("Ok )")
    raise Exception("WTF?")

    print("Never printed (((") 

Из плюсов — стандартность, отсутствие хаков с inspect.stack в реализации, отсутствие необходимости привязывать все к функции целиком (контекст можно задать через with), возможность передавать stack как параметр куда угодно.

См. docs.python.org/3/library/contextlib.html#contextlib.ExitStack и www.wefearchange.org/2013/05/resource-management-in-python-33-or.html

UPD: под 2.х можно поставить contextlib2.readthedocs.org/en/latest/
В Common Lisp этот механизм существенно совершеннее, гуглить «unwind-protect»
Так я из поста и не понял, в чём же defer лучше исключений в контексте Python? В вашем примере было бы логичнее использовать with open(...) as f:.
он не лучше и не хуже, дефер просто отложенная функция, которая выполнится перед выходом из функции, но учитывая что в го нет try… catch там есть волшебная функция panic которая плюет на все и (грубо говоря) делает return причем это все происходит пока этот ретурн не будет остановлен. В сумме эти функции могут работать для обработки ошибок, как и try… catch разница лишь в том что нет обрамлений в скобочки при try (читай отступов)
Выглядит забавно, но практической пользы нет. Слишком отклоняется от python way.
Sign up to leave a comment.

Articles