Сообщить об ошибке.

Контекстные менеджеры c повторным входом

Более сложные контекстные менеджеры могут быть 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 с другим потоком.