1

I understand how an object can be extended to be also used as a context manager. I also understand how one can easily create a context manager from a (generator) function using contextlib.

However, is it possible to write a function that would behave as a function when used as a function,

foo = make_foo()

and as a context manager when used as a context manager,

with make_foo() as foo:
  ...

Looking around, I would say that this is not possible -- however isn't that precisely the behavior of the open function? Is this behavior only possible for builtin functions, or can it also be achieved with python code?

user209974
  • 1,737
  • 2
  • 15
  • 31
  • 3
    When you write `with make_foo() as foo:`, it isn't the function itself that is the context manager, it's whatever object is returned by the function. The only requirement is that the returned object have `__enter__()` and `__exit__()` methods. So you couldn't return an `int` or `str` from the function and also use it as a context manager, but you could define a subclass of those types that would work. – jasonharper Mar 17 '20 at 21:44
  • 1
    There's nothing too magical happening in the `with` statement. After `make_foo()` returns an object (call it `obj`), `foo` is bound to `obj.__enter__()`, not `obj` itself. It's the return value of `make_foo`, not `make_foo` itself, that acts as the context manager. – chepner Mar 17 '20 at 21:44
  • 1
    Typically, the objects returned by `open` have their `__enter__` methods simply return `self`. – chepner Mar 17 '20 at 21:46
  • @user209974 ... are you asking for something like this: https://pastebin.com/39t6H9X5 – Todd Mar 17 '20 at 22:02

0 Answers0