Я понимаю, как можно расширить объект, чтобы его также можно было использовать в качестве менеджера контекста. Я также понимаю, как можно легко создать диспетчер контекста из функции (генератора), используя contextlib
.
Однако можно ли написать функцию, которая будет вести себя как функция при использовании в качестве функции,
foo = make_foo()
и как диспетчер контекста при использовании в качестве диспетчера контекста,
with make_foo() as foo:
...
Оглядевшись вокруг, я бы сказал, что это невозможно, но разве не так ведет себя функция open
? Возможно ли такое поведение только для встроенных функций или его также можно достичь с помощью кода Python?
with make_foo() as foo:
, менеджером контекста является не сама функция, а любой объект, возвращаемый функцией. Единственное требование состоит в том, чтобы возвращаемый объект имел методы__enter__()
и__exit__()
. Таким образом, вы не могли вернутьint
илиstr
из функции, а также использовать ее в качестве диспетчера контекста, но вы могли определить подкласс этих типов, который будет работать. - person jasonharper   schedule 18.03.2020with
не происходит ничего сверхъестественного. После того, какmake_foo()
возвращает объект (назовем егоobj
),foo
привязывается кobj.__enter__()
, а не к самомуobj
. Именно возвращаемое значениеmake_foo
, а не самоmake_foo
действует как менеджер контекста. - person chepner   schedule 18.03.2020__enter__
объектов, возвращаемыхopen
, просто возвращаютself
. - person chepner   schedule 18.03.2020