【问题标题】:Python - Try/ResumePython - 尝试/恢复
【发布时间】:2016-11-10 21:56:04
【问题描述】:

我正在寻找一种在处理异常后从其所在位置恢复代码的方法。具体来说,我遇到了一个问题,我试图单击不同的按钮,但有时会出现一个弹出窗口并中断该过程。我无法预测弹出窗口何时会发生,但无论何时发生,我都需要从上次中断的地方继续。我能想到的唯一编码方法是这样的:

try:
    click_button_1()
except:
    handle_pop_up()
    click_button_1()

try:
    click_button_2()
except:
    handle_pop_up()
    click_button_2()

try:
    click_button_3()
except:
    handle_pop_up()
    click_button_3()

显然,这是一种非常不切实际的编码方式,因为每一行都必须在自己的 try/except 块中,但我似乎找不到更好的方法。

编辑:大家不用担心,在我使用这个时会有特定的例外:) 我只是使用了 except: 为简单起见。

【问题讨论】:

  • 可以使用重试装饰器。我正在输入一个答案。

标签: python


【解决方案1】:

如果有几个函数必须处理相同类型的异常并以相同的方式处理它,我会编写一个装饰器并装饰所有它们:

def with_exception_handling(func):
    def handled_func(*a, **kw):
        try:
            func(*a, **kw)
        except Exception:
            handle_pop_up()
            func(*a, **kw)

然后分别装饰它们:

@with_exception_handling
def click_button_1():
    ...

@with_exception_handling
def click_button_2():
    ...

@with_exception_handling
def click_button_3():
    ...

稍后,只需使用它们:

click_button_1()
click_button_2()
click_button_3()

编辑:多次捕获异常

Sam 在 cmets 中询问使用装饰器的解决方案,但要处理多个异常(如在 Alex's answer 中)。

两者都很容易做到:

def with_multiple_exception_handling(func):
    def handled_func(*a, **kw):
        while True:
            try:
                func(*a, **kw)
            except Exception:
                handle_pop_up()
            else:
                break

免责声明:当然,这可能需要也可能不需要,视情况而定。此外,我宁愿不抓住通用的Exception。而不是这样,应该以这种方式处理预期的特定异常。

【讨论】:

  • 我真的很喜欢这个解决方案,因为我觉得它使代码保持干净且易于阅读。但是,我也喜欢 Alex 的回答支持多次捕获相同的错误。有没有办法将它添加到这个解决方案中?我在 with_exception_handling() 中的 try/except 周围添加了一个 while 循环,但它似乎没有做任何事情。
  • @SamKrygsheld 我在答案中添加了多个异常处理代码。
  • 谢谢!另外,经过测试,似乎异常处理程序需要返回该函数,否则会得到一个 Nonetype is not callable 异常,请参阅此答案:stackoverflow.com/questions/25877767/…
【解决方案2】:
for func in [click_button_1,
             click_button_2,
             click_button_3]:
    while True:
        try:
            func()
        except:  # you should really put a specific exception here
            handle_pop_up()
        else:
            break

while 循环是为了确保即使问题多次发生也能正常运行。

【讨论】:

    【解决方案3】:

    你可以使用重试装饰器。

    from retrying import retry
    def my_exception(exception):
        #should really catch particular exceptions, implement the next 
        #if isinstance(exception,yourexceptiontype)
        print "Saw an exception"
    
    @retry(retry_on_exception=my_exception, hook=handle_pop_up)
    def run():
    
         click_button_1()
         click_button_2() #and continue
    

    【讨论】:

    • ImportError: No module named 'retrying'
    • 运行 - pip install 重试
    • (1) 应该是hook=handle_pop_up 没有() (2) 你在def run 之后错过了() (3) 在这些修复之后我得到TypeError: 'exceptions.Exception' object is not callableTypeError: __init__() got an unexpected keyword argument 'hook' 如果我删除了 Exception 参数 (4) 如果我只使用 @retry 这将重试整个函数,而不是 OP 想要的单个行。
    • 嘿,我修好了,错别字抱歉
    • 我得到与 Alex Hall 相同的结果 - 意外的关键字参数 'hook' 并重试整个函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-02
    • 1970-01-01
    • 2021-11-14
    • 2016-05-10
    • 1970-01-01
    • 2021-08-19
    • 2017-08-16
    相关资源
    最近更新 更多