Вы можете сохранить созданный объект в переменной, например:
if some_condition:
cm = ContextManager(**args)
else:
cm = OtherContextManager(**other_args)
with cm as contex:
... # some block
Вышесказанное может быть легко расширено до трех возможных менеджеров контекста и т. Д. Вы также можете решить, например, сначала «исправить»менеджер контекста перед «входом» в контекст.
Хотя обычно встречается такой шаблон, как with foo() as bar:
, на самом деле Python просто оценивает foo()
, получает этот элемент и вызывает .__enter__()
для объекта,Результат этого метода сохраняется в bar
.
Так что в вызове foo()
нет ничего «особенного», вы можете использовать любой тип объекта с левой стороны,Таким образом, например, вы можете инкапсулировать логику if
- else
в отдельную функцию и вернуть менеджер контекста, а затем использовать переменную или передать менеджеры контекста в качестве параметров.Пока вы используете его в операторе with
, Python будет вызывать .__enter__(..)
и .__exit__(..)
за занавесом.