Большинство контекстных менеджеров написаны таким образом, что они могут эффективно использоваться в операторе with
только в один раз. Такие "одноразовые" менеджеры контекста должны создаваться заново каждый раз перед использованием. Когда они используются - попытка использовать их во второй раз вызовет исключение или будет работать неправильно.
Это общее ограничение означает, которое рекомендует создавать менеджеры контекста непосредственно в заголовке оператора with
, где они используются.
Файлы являются примером одноразовых контекстных менеджеров, поскольку первый оператор with
закрывает файл, предотвращая любые дальнейшие операции ввода-вывода с использованием этого файлового объекта.
Менеджеры контекста, созданные с помощью декоратора @contextmanager()
, также являются менеджерами контекста одноразового использования и будут ругаться на то, что базовый генератор не сможет дать результат, если будет предпринята попытка использовать его во второй раз:
from contextlib import contextmanager @contextmanager def singleuse(): print("Before") yield print("After") context_manager = singleuse() with context_manager: pass # Before # After # пробуем запустить # второй раз with context_manager: pass # Traceback (most recent call last): # ... # RuntimeError: generator didn't yield