Python中的简明异常处理

Ice*_*dor 4 python exception-handling

我喜欢避免"在你跳跃之前"的范例,因为我重视易于阅读的代码.在某些情况下,我无法预测是否会发生错误,例如资源可用性或内存不足错误.我还没有找到一种干净的方式来编写重复或冗长的代码来处理这些场景.

以下示例略有可读性,但重复代码是不可接受的.

try:
    myobject.write(filename)
except OSError:
    if prompt("%s is in use by another application." +
              "Close that application and try again.") == "Try again":
        myobject.write(filename) #repeated code
Run Code Online (Sandbox Code Playgroud)

为了删除重复的代码,我必须添加更多行并缩进所有内容,从而降低可读性.

success = False
while not success:
    try:
        myobject.write(filename)
        success = True
    except OSError:
        if prompt("%s is in use by another application." +
                  "Close that application and try again.") != "Try again":
            break
Run Code Online (Sandbox Code Playgroud)

有没有一种更短的方式在Python中写这个不重复代码?

dan*_*ano 6

除了切换到while True,您可以添加retry装饰器,并将您的可重试代码移动到由retry以下装饰的函数:

from functools import wraps
from functools import update_wrapper


def retry(prompt_text="An error occured! Retry (y/n)?", 
          prompt_match='y',
          exception=Exception):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            while True:
                try:
                    ret = func(*args, **kwargs)
                    break
                except exception:
                    if raw_input(prompt_text) == prompt_match:
                        ret = None
                        break
            return ret 
        return update_wrapper(wrapper, func)
    return decorator

@retry(prompt_text="your prompt: ", prompt_match="quit", exception=OSError)
def do_write(myobject, filename):
    myobject.write(filename)

if __name__ == "__main__":
    myobject = ...
    filename = ...
    do_write(myobject, filename) # This will be retried.
Run Code Online (Sandbox Code Playgroud)

不过,如果你在不止一个地方使用这种模式,这可能是值得的.