This sort of can be made to work, but is not a good way to go about it. get_file()
returns is a generator function, and calling it returns a specialised generator iterator object, not the open file object itself, not directly.
It works when you use the next()
on the generator to work with the file:
f = get_file()
do_stuff(next(f))
Here next()
advances the generator to the yield
point and returns whatever was yielded. At that point the context for the with open(...) as f:
remains active and the file is not going to be closed.
However, to then close the file you'd have to call next()
again and prevent the StopIteration
exception from being raised:
next(f, None) # give `next()` a default to return when the generator exists
That's not really ideal. You want to wrap your function in a @contextlib.contextmanager()
decorator, which requires that the decorated function is a generator. You can then must use get_file()
as a context manager:
from contextlib import contextmanager
@contextmanager
def get_file():
with open("file.csv", "rb") as f:
yield f
with get_file() as f:
do_stuff(f)
There is not much point in using get_file()
like this, because you may as well just use return open("file.csv", "rb")
and rely on the file object itself being the context manager. But if you were to add other tasks to the get_file()
function that need access to the file or need to know that you closed it, then you may well have a good use-case for a custom context manager.