By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,562 Members | 1,222 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,562 IT Pros & Developers. It's quick & easy.

Safely dealing with arbitrary file objects

P: n/a
I have found myself writing functions rather like these:

def openfile(filename):
if filename == '-':
# convention for shell scripts in Unix-land is to use
# '-' for stdin/stdout for reading/writing.
outfile = sys.stdout
if filename == '2-':
outfile = sys.stderr
else:
outfile = file(filename, 'w')
return outfile

def closefile(fileobj):
# don't close standard file objects, or their replacements
if not fileobj in (sys.stdout, sys.stderr, sys.stdin,
sys.__stdout__, sys.__stderr__, sys.__stdin__):
fileobj.close()
def processfile(filename):
outfile = openfile(filename)
try:
# lots of processing here, which may raise exceptions
var = "stuff happens"
outfile.write(var)
finally:
closefile(outfile)

A question:

I know I'm being paranoid about not closing files I shouldn't close, but
am I being excessively paranoid, or not paranoid enough?

Suggestions for improvements welcome; while I'm happy to read suggestions
using the new with statement, I can't yet rely on having Python 2.5 or
better so I have to stick to try...finally.
--
Steven.
Oct 14 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Steven D'Aprano wrote:
I have found myself writing functions rather like these:

def openfile(filename):
if filename == '-':
# convention for shell scripts in Unix-land is to use
# '-' for stdin/stdout for reading/writing.
outfile = sys.stdout
if filename == '2-':
outfile = sys.stderr
else:
outfile = file(filename, 'w')
return outfile

def closefile(fileobj):
# don't close standard file objects, or their replacements
if not fileobj in (sys.stdout, sys.stderr, sys.stdin,
sys.__stdout__, sys.__stderr__, sys.__stdin__):
fileobj.close()
def processfile(filename):
outfile = openfile(filename)
try:
# lots of processing here, which may raise exceptions
var = "stuff happens"
outfile.write(var)
finally:
closefile(outfile)

A question:

I know I'm being paranoid about not closing files I shouldn't close, but
am I being excessively paranoid, or not paranoid enough?

Suggestions for improvements welcome; while I'm happy to read suggestions
using the new with statement, I can't yet rely on having Python 2.5 or
better so I have to stick to try...finally.
How about a wrapper that passes along all but 'close', so you don't
have to worry about closing something you means to leave open.
Something like:

class DontCloseOutput(file):
'''subclass file only to allow isinstance checks to work out'''
def __init__(self, referent):
self._actual = referent
self.closed = False

def close(self):
self.closed = True

def write(self, data):
if self.closed:
raise IOError('Tried to write closed pseudo-file')
return self._actual.write(data)
def writeopen(filename):
if filename == '-':
# convention for shell scripts in Unix-land is to use
# '-' for stdin/stdout for reading/writing.
return DontCloseOutput(sys.stdout)
if filename == '2-':
return DontCloseOutput(sys.stderr)
else:
return open(filename, 'w') # BTW, open is the preferred way
# file was for a short time.

You of course can do similar things (probably forwarding more message)
with readopen.

-Scott David Daniels
Sc***********@Acm.Org
Oct 14 '07 #2

P: n/a
On Oct 14, 5:01 am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.auwrote:
I have found myself writing functions rather like these:

def openfile(filename):
if filename == '-':
# convention for shell scripts in Unix-land is to use
# '-' for stdin/stdout for reading/writing.
outfile = sys.stdout
if filename == '2-':
outfile = sys.stderr
else:
outfile = file(filename, 'w')
return outfile

def closefile(fileobj):
# don't close standard file objects, or their replacements
if not fileobj in (sys.stdout, sys.stderr, sys.stdin,
sys.__stdout__, sys.__stderr__, sys.__stdin__):
fileobj.close()

def processfile(filename):
outfile = openfile(filename)
try:
# lots of processing here, which may raise exceptions
var = "stuff happens"
outfile.write(var)
finally:
closefile(outfile)

A question:

I know I'm being paranoid about not closing files I shouldn't close, but
am I being excessively paranoid, or not paranoid enough?

Suggestions for improvements welcome; while I'm happy to read suggestions
using the new with statement, I can't yet rely on having Python 2.5 or
better so I have to stick to try...finally.
With with:

import sys

class leave_open(object):
def __init__(self, obj):
self.obj = obj
def __enter__(self):
return self.obj
def __exit__(self, *exc_info):
pass

def open_file(name, special={'-':sys.stdout, '2-':sys.stderr}):
if name in special:
return leave_open(special[name])
else:
return open(name, 'w')

def process_file(filename):
with open_file(filename) as outfile:
outfile.write("stuff happens")
Without with:

import sys

def open_file(name, special={'-':sys.stdout, '2-':sys.stderr}):
if name in special:
return False, special[name]
return True, open(name, 'w')

def process_file(filename):
should_close, outfile = open_file(filename)
try:
outfile.write('stuff happens')
finally:
if should_close:
outfile.close()

--
Paul Hankin

Oct 14 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.