I often see this in code:
with open(file_path) as f:
json_content = json.load(f)
And less often this:
json_content = json.load(open(file_path))
I was wondering if the latter is an anti pattern or what the difference between the two versions is.
json.load(open(file_path)) relies on the GC to close the file. That's not a good idea: If someone doesn't use CPython the garbage collector might not be using refcounting (which collects unreferenced objects immediately) but e.g. collect garbage only after some time.
Since file handles are closed when the associated object is garbage collected or closed explicitly (
.__exit__() from a context manager) the file will remain open until the GC kicks in.
with ensures the file is closed as soon as the block is left - even if an exception happens inside that block, so it should always be preferred for any real application.
When you use a context manager, it guarantees that your file will be close automatically at the end of block. The
with statement does this by calling the
close attribute of the file object, using its
As said in document:
The with statement guarantees that if the
__enter__()method returns without an error, then
__exit__()will always be called.
Read about more features https://docs.python.org/3.5/reference/compound_stmts.html#with
In addition to other answers, a context manager is very similar to the try-finally clause.
with open(file_path) as f: json_content = json.load(f)
can be written as:
f = open(file_path) try: json_content = json.load(f) finally: f.close()
The former is clearly preferable.