如何避免重复异常处理?

时间:2009-10-26 12:27:27

标签: python exception-handling

我已经将IOError处理移动到一个单独的函数,以避免在打开文件进行读取时出现样板。

但是如果在读取文件时IOError会触发怎么办?如果sshfs断开连接,或者文件被root删除等?

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 个答案:

答案 0 :(得分:7)

我可能会尝试将文件操作移动到单独的函数中并将它们包装在try ...中除外

实际上我只是有了更好的想法......将错误处理放入装饰器中并将装饰器应用于执行文件操作的每个函数

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)