Менеджер контекста - это то, что вы можете использовать с оператором with
. Он явно предназначен для:
- выполнить настройку,
- даст вам объект, а
- снова выполнить какое-либо разложение (даже если вы подняли исключение).
Например, open
может использоваться как менеджер контекста. В следующем коде
with open(...) as f:
# do stuff
не имеет значения, что такое stuff
, файл всегда будет закрыт. (Ну, обычно. За исключением глупых случаев, таких как отключение питания или остановка процесса.)
Вам следует использовать менеджер контекста, когда вы находитесь в такой ситуации. Это не выглядит так, как ты, поэтому я не вижу причин для менеджера контекста.
Существует альтернативный (не лучше и не хуже, просто другой) способ написания кода, использующий менеджер контекста. Если вы хотите временно перенаправить stdout
- но убедитесь, что вы восстановили его, когда закончили - тогда вы находитесь в ситуации выше. Вот пример:
@contextlib.contextmanager
def redirect_stdout(stream):
import sys
sys.stdout = stream
yield
sys.stdout = sys.__stdout__
Затем вы можете написать код, как
with open(...) as f:
with redirect_stdout(f):
# do stuff
и любые записи на стандартный вывод в stuff
вместо этого перейдут на f
.
РЕДАКТИРОВАТЬ: Вы правы, что нет никакого способа, чтобы иметь контекстный менеджер: либо вы в одном или нет. Вы всегда можете написать свой, который ничего не может сделать:
@contextlib.contextmanager
def maybe_open(path, do_nothing=True):
if do_nothing:
f = None
yield sys.stdout
else:
f = open(path)
yield f
if f:
f.close()
Это почти наверняка излишне.