Chris Lawlor
Chris Lawlor

Reputation: 48902

Should a class or method which processes a file close the file as a side effect?

I'm wondering which is the more 'Pythonic' / better way to write methods which process files. Should the method which processes the file close that file as a side effect? Should the concept of the data being a 'file' be completely abstracted from the method which is processing the data, meaning it should expect some 'stream' but not necessarily a file?:

As an example, is it OK to do this:

process(open('somefile','r'))
... carry on

Where process() closes the file handle:

def process(somefile):
    # do some stuff with somefile
    somefile.close()

Or is this better:

file = open('somefile','r')
process(file)
file.close()

For what it's worth, I generally am using Python to write relatively simple scripts that are extremely specifically purposed, where I'll likely be the only one ever using them. That said, I don't want to teach myself any bad practices, and I'd rather learn the best way to do things, as even a small job is worth doing well.

Upvotes: 2

Views: 153

Answers (3)

Aaron
Aaron

Reputation: 7098

Generally, it is better practice for the opener of a file to close the file. In your question, the second example is better.

This is to prevent possible confusion and invalid operations.

Edit: If your real code isn't any more complex than your example code, then it might be better just to have process() open and close the file, since the caller doesn't use the file for anything else. Just pass in the path/name of the file. But if it is conceivable that a caller to process() will use the file before the file should be closed, then leave the file open and close operations outside of process().

Upvotes: 4

ymv
ymv

Reputation: 2173

No, because it reduces flexibility: if function doesn't close file and caller doesn't need it - caller can close file. If it does but caller still need file open - caller stuck with reopening file, using StringIO, or something else.

Also closing file object require additional assumptions on it's real type (object can support .read() or .write(), but have no meaningful .close()), hindering duck-typing.

And files-left-open is not a problem for CPython - it will be closed on garbage collection instantly after something(open('somefile')). (other implementation will gc and close file too, but at unspecified moment)

Upvotes: 0

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798536

Using with means not having to worry about this.

At least, not on 2.5+.

Upvotes: 4

Related Questions