Страницы

Поиск по вопросам

понедельник, 25 марта 2019 г.

Как сделать метод пригодным для with?

Есть метод-обертка для загрузки YAML в объект.
def load_yaml(path): with io.open(path, encoding='utf-8') as fp: return yaml.safe_load(fp)
Хочу использовать with с этим методом:
with load_yaml('data.yml') as data: pass
Получаю ошибку:
... with load_yaml('data.yml) as data: AttributeError: __enter__
Что я делаю не так? Какие требования предъявляются к методу, чтобы его можно было использовать с with?


Ответ

Требования предъявляются не к "методу" (у вас, кстати, это не метод, а обычная функция), а к результату, который возвращает этот "метод".
После with вообще может стоять не только вызов функции, но и абсолютно любое выражение - сначала оно будет полностью вычислено, и уже над его результатом будет совершаться with. И вот как раз к этому результату есть определённые требования.
Для того, чтобы объект можно было использовать в with, у этого объекта должны быть определены специальные методы __enter__ и __exit__. Именно в этих методах вы и объясняете интерпретатору, как он должен открыть контекст работы с этим объектом и потом безопасно закрыть его.
Более подробно вы можете нагуглить по запросу "питон контекстный менеджер" или прочитать здесь:
https://habrahabr.ru/post/186608/#context
https://habrahabr.ru/post/196382/

Комментариев нет:

Отправить комментарий