Instead of this:
FILE = open(f) do_something(FILE) FILE.close()
it’s better to use this:
with open(f) as FILE: do_something(FILE)
What if I have something like this?
if f is not None: FILE = open(f) else: FILE = None do_something(FILE) if FILE is not None: FILE.close()
Where do_something also has an “if FILE is None” clause, and still does something useful in that case – I don’t want to just skip do_something if FILE is None.
Is there a sensible way of converting this to with/as form? Or am I just trying to solve the optional file problem in a wrong way?
Advertisement
Answer
If you were to just write it like this:
if f is not None: with open(f) as FILE: do_something(FILE) else: do_something(f)
(file
is a builtin btw )
Update
Here is a funky way to do an on-the-fly context with an optional None that won’t crash:
from contextlib import contextmanager none_context = contextmanager(lambda: iter([None]))() # <contextlib.GeneratorContextManager at 0x1021a0110> with (open(f) if f is not None else none_context) as FILE: do_something(FILE)
It creates a context that returns a None value. The with
will either produce FILE as a file object, or a None type. But the None type will have a proper __exit__
Update
If you are using Python 3.7 or higher, then you can declare the null context manager for stand-in purposes in a much simpler way:
import contextlib none_context = contextlib.nullcontext()
You can read more about these here:
https://docs.python.org/3.7/library/contextlib.html#contextlib.nullcontext