stack user
stack user

Reputation: 863

does this line of python close the file when its finished?

I have a line of python that splits a file by carriage return character:

lines = open(sFile, 'r').read().split("0d".decode('hex'))

Was this file is closed? If not, can I acquire the file handle somehow?

Upvotes: 2

Views: 138

Answers (3)

mgilson
mgilson

Reputation: 310117

The short answer is "probably". The open file object should get garbage collected which will close the file. However, there are some circumstances where that might not be true and the open file handle can live on.

Best practice is to always close your file handles. The beauty of context managers is hard to over-estimate here:

with open(sFile) as input_file:
    lines = input_file.read().split('0d'.decode('hex'))

It has been asked in the comments if we can demonstrate that a file object is implicitly closed. I don't know the answer to that question, however, we can demonstrate that the file object can be reaped by the garbage collector before the current statement is even finished executing. Since it's fairly common knowledge that file objects are closed when reaped we can make some assumptions about what can happen in OP's case.

from __future__ import print_function
import weakref

def callback(*args):
    print('cleanup')

fobj = weakref.ref(open('test.dat'), callback)()
print(fobj)

If you'll notice, cleanup gets printed before None (and that the weakref.ref returns None) which means our file object has been reaped by the garbage collector before the reference is called1.

1Note, this is CPython behavior. Run it on pypy-2.6.1 and the file object is still alive at this point and cleanup never gets printed! This lends support to the claim that you should close your own file handles as there is definitely implementation dependence in when the GC runs (and therefore, when the file handle will be closed and reaped).

Upvotes: 8

alecxe
alecxe

Reputation: 474141

The file may be closed for you implicitly by the garbage collector. There is more to it:

It's recommended to use with context manager when dealing with files or file-like objects:

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

with open(sFile) as input_file:
    lines = input_file.read().split("0d".decode('hex'))

Upvotes: 6

Alejandro Ricoveri
Alejandro Ricoveri

Reputation: 917

The with clause can take care of that for you.

This is the pythonic way to deal with files:

with open(sFile, 'r') as f:
    lines = f.read().split("0d".decode('hex'))

Upvotes: 2

Related Questions