如何避免异常处理的重复?
我把处理输入输出错误的部分移到了一个单独的函数里,这样在打开文件进行读取时就不用重复写很多相似的代码。
但是,如果在读取文件的时候发生了输入输出错误怎么办?比如说,sshfs断开连接了,或者文件被管理员删除了等等。
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(anotherfile, '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)
文件的读取方式有很多种,所以我找不到一个办法把它们放到那个函数里,并把变化的部分作为参数传进去。
[补充:我想到了这个解决方案,但它会生成一个无法关闭的生成器。如果循环被停止,文件就会一直保持打开状态。]
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
1 个回答
7
我可能会尝试把文件操作放到单独的函数里,然后用try...except来处理可能出现的错误。
其实我刚想到一个更好的主意……把错误处理放到一个装饰器里,然后把这个装饰器应用到每个进行文件操作的函数上。
def catch_io_errors(fn):
def decorator(*args, **kwargs):
try:
return fn(*args, **kwargs)
except IOError:
quit('whatever error text')
return decorator
这样你就可以把所有的文件操作放到自己的函数里,然后应用这个装饰器。
@catch_io_errors
def read_file():
with open(myfile, 'r') as f:
for i in f:
print i
或者如果你需要兼容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)