1
votes

Consider the following piece of Python (2.x) code:

for line in open('foo').readlines():
    print line.rstrip()

I assume that since the open file remains unreferenced it has to be closed automatically. I have read about garbage collector in Python which frees memory allocated by unused objects. Is GC general enough to handle the files too?

3

3 Answers

5
votes

Taken from the docs (python 3.6):

If you’re not using the with keyword, then you should call f.close() to close the file and immediately free up any system resources used by it. If you don’t explicitly close a file, Python’s garbage collector will eventually destroy the object and close the open file for you, but the file may stay open for a while. Another risk is that different Python implementations will do this clean-up at different times.

So yes, the file will be closed automatically, but in order to be in control of the process you should do so yourself or use a with statement:

with open('foo') as foo_file:
    for line in foo_file.readlines():
        print line.rstrip()

foo_file will be clsoed once the with block ends

In the python 2.7 docs, the wording is different:

When you’re done with a file, call f.close() to close it and free up any system resources taken up by the open file. After calling f.close(), attempts to use the file object will automatically fail.

so I assume that you should not depend on the garbage collector automatically closing files for you and just do it manually/use with

0
votes

It depends on what you do, check out this description how it works.

In general I would recommend to use the context manager of the file:

with open("foo", "r") as f:
    for line in f.readlines():
    # ....

which is similar to (for basic understanding):

file_context_manager = open("foo", "r").__enter__()
for line in file_context_manager.readlines():
    # ....
file_context_manager.__exit__()

The first version is a lot more readable, and the withstatement calls the exit method automatically (plus a bit more context handling). The file will be closed automatically when the scope of the with statement is left.

0
votes

I often use open without with so I ran a little test. For the test I use Python 3.9 so I'm not speaking of earlier versions but for 3.9 at least, we do not need the with to have a clean file close.

bash

 inotifywait -m "testfile"

python3.9

 lines=[line for line in open("testfile")]
 sleep(5)
 for line in lines:
    print(line)

Watch the inotifywait window and run the python script. Before the sleep the final event will be CLOSE_NOWRITE,CLOSE and there will be no other events from that file through the run of the python script.