How to avoid repetition of exception handling?
I've moved IOError handling to a separate function to avoid boilerplate when opening files for reading.
But what if IOError fires when the file is being read? If sshfs disconnects, or file is deleted by root, etc.?
def safe_open(*args):
try:
return open(*args)
except IOError:
quit('Error when opening file \'{0}\'. Error #{1[0]}: {1[1]}'.format(\
args[0], sys.exc_info()[1].args))
...
with safe_open(myfile, 'r') as f:
for i in f:
print i
with safe_open(anotherfi开发者_如何学Gole, 'r') as f:
try:
conf = ''.join(f).format(**args)
except KeyError:
quit('\nOops, your template \'{0}\' has placeholders for' + \
'parameters\nthat were not supplied in the command line: - {1}\n' +
'\nCan\'t proceed. Ending. Nothing has been changed yet.'.format( \
args['host_template'], '\n - '.join(sys.exc_info()[1].args)), 1)
File is read in different ways, so I don't see a way to put it into the function and pass the changing part as arguments.
[Added: thought of this solution, but it makes a generator that can't be closed. If a loop is stopped, the file is left open.]
def reader(*args):
try:
with safe_open(*args) as f:
for i in f:
yield i
except IOError:
print('IOError when trying to read \'{0}\''.format(args[0]))
for i in reader(myfile, 'r'):
pass # do some job
I would probably try move the file operations into separate functions and wrap those in a try... except
actually I just got an even better idea... put the error handling into a decorator and apply the decorator to each of the functions that does file operations
def catch_io_errors(fn):
def decorator(*args, **kwargs):
try:
return fn(*args, **kwargs)
except IOError:
quit('whatever error text')
return decorator
then you can put all file ops into their own functions and apply the decorator
@catch_io_errors
def read_file():
with open(myfile, 'r') as f:
for i in f:
print i
or if you need compatibility with python 2.3:
def read_file():
f = open(myfile, 'r')
for i in f:
print i
f.close()
read_file = catch_io_errors(read_file)
精彩评论