-1

For file I/O what is the purpose of:

with open

and should I use it instead of:

 f=open('file', 'w')
 f.write('foo)'
 f.close()
Joseph
  • 327
  • 5
  • 17

4 Answers4

8

Always use the with statement.

From docs:

It is good practice to use the with keyword when dealing with file objects. This has the advantage that the file is properly closed after its suite finishes, even if an exception is raised on the way. It is also much shorter than writing equivalent try-finally blocks.

If you don't close the file explicitly then the file object may hang around in the memory until it is garbage collected, which implicitly calls close() on the file object. So, better use the with statement, as it will close the file explicitly even if an error occurs.

Related: Does a File Object Automatically Close when its Reference Count Hits Zero?

Community
  • 1
  • 1
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • 1
    +1. But the docs don't mention that the file is also closed if you forget to call `close`. Or if you add a `return` in the middle of the function without also adding a `close`. And it's shorter. And it's more obvious to the reader that you closed the file, so if I'm trying to debug your code, I don't have to go checking all the code paths to make sure the bug isn't that you leaked the file. And so on. – abarnert Nov 08 '13 at 22:33
  • @abarnert Yes, it weird that nothing is mentioned about it in the file IO part, but a small line can be found in the [tempfile](http://docs.python.org/2/library/tempfile.html#tempfile.TemporaryFile) module's docs: *(including an implicit close when the object is garbage collected)*. – Ashwini Chaudhary Nov 08 '13 at 22:53
  • I don't know if it's really _weird_, or even a deficiency in the docs. The exception problem is the hardest part of the problem to solve, and so they tell you it solves that, and leave you to figure out that it also solves all the simpler problems. That may not be sufficient for someone reading one paragraph on its own, but it may be fine for someone learning by working through the tutorial in order, and that's what the tutorial was really written for. – abarnert Nov 09 '13 at 00:19
1

Yes. You should use with whenever possible.

This is using the return value of open as a context manager. Thus with is used not just specifically for open, but it should be preferred in any case that some cleanup needs to occur with regards to the object (that you would normally put in a finally block). In this case: on exiting the context, the .close() method of the file object is invoked.

Another good example of a context manager "cleaning up" is threading's Lock:

lock = Lock()

with lock:
    #do thing
#lock is released outside the context

In this case, the context manager is .release()-ing the lock.

Anything with an __enter__ and __exit__ method can be used as a context manager. Or, better, you can use contextlib to make context managers with the @contextmanager decoration. More here.

roippi
  • 25,533
  • 4
  • 48
  • 73
  • It's actually the file object returned by `open` that's a context manager, not the `open` function. But that's a minor quibble, and the overall explanation is great (especially giving `lock` as an obvious but completely unrelated example). – abarnert Nov 09 '13 at 00:21
  • Yeah, I stumbled my way into mentioning the file handle at some point.. I'll reword. – roippi Nov 09 '13 at 00:24
0

Basically what it is trying to avoid is this:

set things up
try:
    do something
finally:
    tear things down

but with the with statement you can safely, say open a file and as soon as you exit the scope of the with statement the file will be closed.

The with statement calls the __enter__ function of a class, which does your initial set up and it makes sure it calls the __exit__ function at the end, which makes sure that everything is closed properly.

jramirez
  • 8,537
  • 7
  • 33
  • 46
-1

The with statement is a shortcut for easily writing more robust code. This:

with open('file', 'w') as f:
    f.write('foo')

is equivalent to this:

try:
    f = open('file', 'w')
    f.write('foo')
finally:
    f.close()
Izkata
  • 8,961
  • 2
  • 40
  • 50