Reputation: 13175
This question is purely out of curiosity. Brought up in a recent discussion for a question here, I've often wondered why the context manager (with
) does not throw an error when people explicitly close the file anyway through misunderstanding... and then I found that you can call close()
on a file multiple times with no error even without using with
.
The only thing we can find relating to this is here and it just blandly says (emphasis mine):
close( )
Close the file. A closed file cannot be read or written any more. Any operation which requires that the file be open will raise a ValueError after the file has been closed. Calling close() more than once is allowed.
It would appear that this is intentional by design but, if you can't perform any operations on the closed file without an exception, we can't work out why closing the file multiple times is permitted. Is there a use case?
Upvotes: 2
Views: 1430
Reputation: 309831
Resource management is a big deal. It's part of the reason why we have context managers in the first place.
I'm guessing that the core development team thought that it is better to make it "safe" to call close more than once to encourage people to close their files. Otherwise, you could get yourself into a situation where you're asking "Was this closed before?". If .close()
couldn't be called multiple times, the only option would be to put your file.close()
call in a try
/except
clause. That makes the code uglier and (frankly), lots of people probably would just delete the call to file.close()
rather than handle it properly. In this case, it's just convenient to be able to call file.close()
without worrying about any consequences since it's almost certain to succeed and leave you with a file that you know is closed afterward.
Upvotes: 6
Reputation: 23203
Function call fulfilled its promise - after calling it file is closed. It's not like something failed, it's just you did not have to do anything at all to ensure condition you we're asking for.
Upvotes: 1
Reputation: 101919
Thinking about with
is just wrong. This behaviour has been in Python forever and thus it's worth keeping it for backward compatibility.
Because it would serve no purpose to raise an exception. If you have an actual bug in your code where you might close the file before finishing using it, you'll get an exception when using the read
or write
operations anyway, and thus you'll never reach the second call to close
.
Allowing this will rarely make the code easier to write avoiding adding lots of if not the_file.isclosed(): the_file.close()
.
The BDFL designed the file objects in that way and we are stuck with that behaviour since there's no strong reason to change it.
Upvotes: 6