Instead of this:
FILE = open(f)
do_something(FILE)
FILE.close()
it\'s better to use this:
with open(f) as FILE:
do_some
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
While all of the other answers are excellent, and preferable, note that the with
expression may be any expression, so you can do:
with (open(file) if file is not None else None) as FILE:
pass
Note that if the else
clause were evaluated, to yield None
this would result in an exception, because NoneType
does not support the appropriate operations to be used as a context manager.
This seems to solve all of your concerns.
if file_name is not None:
with open(file_name) as fh:
do_something(fh)
else:
do_something(None)
Since Python 3.7, you can also do
from contextlib import nullcontext
with (open(file) if file else nullcontext()) as FILE:
# Do something with `FILE`
pass
See the official documentation for more details.
something like:
if file: #it checks for None,false values no need of "if file is None"
with open(file) as FILE:
do_something(FILE)
else:
FILE=None