I have read that when file is opened using the below format
with open(filename) as f:
#My Code
f.close()
explicit closing of file is not required . Can someone explain why is it so ? Also if someone does explicitly close the file, will it have any undesirable effect ?
Closing is not required because the
with
statement automatically takes care of that.Within the
with
statement the__enter__
method onopen(...)
is called and as soon as you go out of that block the__exit__
method is called.So closing it manually is just futile since the
__exit__
method will take care of that automatically.As for the
f.close()
after, it's not wrong but useless. It's already closed so it won't do anything.Also see this blogpost for more info about the
with
statement: http://effbot.org/zone/python-with-statement.htmThe mile-high overview is this: When you leave the nested block, Python automatically calls
f.close()
for you.It doesn't matter whether you leave by just falling off the bottom, or calling
break
/continue
/return
to jump out of it, or raise an exception; no matter how you leave that block. It always knows you're leaving, so it always closes the file.*One level down, you can think of it as mapping to the
try:
/finally:
statement:One level down: How does it know to call
close
instead of something different?Well, it doesn't really. It actually calls special methods
__enter__
and__exit__
:And the object returned by
open
(afile
in Python 2, one of the wrappers inio
in Python 3) has something like this in it:It's actually a bit more complicated than that last version, which makes it easier to generate better error messages, and lets Python avoid "entering" a block that it doesn't know how to "exit".
To understand all the details, read PEP 343.
In general, this is a bad thing to do.
However, file objects go out of their way to make it safe. It's an error to do anything to a closed file—except to
close
it again.* Unless you leave by, say, pulling the power cord on the server in the middle of it executing your script. In that case, obviously, it never gets to run any code, much less the
close
. But an explicitclose
would hardly help you there.