все Python 3ООПконструкция
with
контекст. менеджер
Оператор with выполняет блок под контекстным менеджером: __exit__ вызывается при любом выходе из блока — обычном, по return или по исключению.
Синтаксис
with expr as name:
...
with a as x, b as y:
...
with (
open('a') as fa,
open('b') as fb,
):
...
with гарантирует уборку (закрыть файл, отпустить блокировку), но не ловит ошибку: исключение летит дальше, если __exit__ не вернул True — так работает contextlib.suppress, и так же легко случайно проглотить все ошибки. Несколько менеджеров пишутся через запятую и закрываются в обратном порядке; с 3.10 их можно взять в скобки и разнести по строкам. Переменная после as не исчезает после блока: файл f остаётся доступен как объект, но уже закрыт, и f.read() даст ValueError. И as получает результат __enter__, а не сам менеджер — у open() это одно и то же, у других менеджеров нет.
Примеры
with open('a.txt', 'w', encoding='utf-8') as f:
f.write('данные')
print(f.closed) # → True — имя f живо, но файл закрыт
# Python 3.9+
class Tag:
def __init__(self, name, swallow=False):
self.name, self.swallow = name, swallow
def __enter__(self):
print('вход', self.name)
return self.name.upper()
def __exit__(self, exc_type, exc, tb):
print('выход', self.name, exc_type.__name__ if exc_type else None)
return self.swallow # True — исключение подавлено
with (
Tag('a', swallow=True) as x,
Tag('b') as y,
):
print(x, y) # → A B
1 / 0
print('дошли сюда') # → дошли сюда
from contextlib import suppress
with suppress(FileNotFoundError):
open('нет-такого.txt')
print('ошибка подавлена') # → ошибка подавлена
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности