Skip to main content
 首页 » 编程设计

python之如何避免异常处理的重复

2025年05月04日14insus

我已将 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 

请您参考如下方法:

我可能会尝试将文件操作移动到单独的函数中并将它们包装在一个 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)