Более сложные контекстные менеджеры могут быть c повторным входом. Эти менеджеры контекста могут не только использоваться в нескольких операторах with
, но также могут использоваться внутри оператора with
, который уже использует тот же менеджер контекста.
Вот очень простой пример повторного использования:
from contextlib import redirect_stdout from io import StringIO stream = StringIO() write_to_stream = redirect_stdout(stream) with write_to_stream: print("Пишем в поток, а не в стандартный вывод") with write_to_stream: print("Здесь также пишется в поток") >>> print("Пишем на стандартный вывод") # Пишем на стандартный вывод >>> print(stream.getvalue()) # Пишем в поток, а не в стандартный вывод # Здесь также пишется в поток
Реальные примеры повторного входа с большей вероятностью включают несколько функций, вызывающих друг друга и следовательно, будут намного сложнее, чем этот пример.
Обратите внимание, что контекстные менеджеры с повторным входом потоко НЕ безопасны.
Например, функция contextlib.redirect_stdout()
не является потоко-ориентированной, поскольку она вносит глобальные изменения в состояние системы, связывая sys.stdout
с другим потоком.