用于在异常时重新尝试代码块的设计模式

时间:2014-12-25 23:40:29

标签: python design-patterns

我正在努力寻找一种设计模式 - 因为我确信存在一种设计模式,这个问题很常见。

在我的应用程序中,如果用户丢失了Internet连接,我希望能够暂停应用程序,允许用户检查其连接并重试。当连接成功时,应用程序会离开它停止的位置。

我试过这样:

while True:
   try:
       for url in urls:
           downloadPage(url)
   except ConnectionException:
       raw_input('Connection lost. Press enter to try again')
       continue

但这不起作用,因为如果在for循环中引发异常,它将捕获它,但是当它继续时它将从urls列表的开头重新启动。

我确实需要在应用程序开始运行之前和每次请求期间检查连接错误。这样我可以暂停它。但是我不希望用try/catch块来丢弃我的所有代码。

有这种模式吗?

5 个答案:

答案 0 :(得分:1)

您可以在for循环中移动try

for url in urls:
    while True:
        try:
            downloadPage(url)
        except ConnectionException:
            raw_input('Connection lost. Press enter to try again')

答案 1 :(得分:1)

为什么不呢?

while True:
   for url in urls:
       success = False
       while (not success):
           try:
               downloadPage(url)
               success = True
           except ConnectionException:
               raw_input('Connection lost. Press enter to try again')

答案 2 :(得分:1)

这将尝试连接最多3次,然后再删除当前网址并继续下一个网址。因此,如果无法建立连接,您就不会被卡住,但仍然为每个网址提供了公平的机会。

for url in urls:
    retries = 3
    while True:
        try:
            downloadPage(url)
        except ConnectionException:
            retries -= 1
            if retries == 0:
                print "Connection can't be established for url: {0}".format(url)
                break            
            raw_input('Connection lost. Press enter to try again')

答案 3 :(得分:1)

你可以"摘要"只有一个地方的残骸(没有"把我的所有代码都用try / catch块丢弃"正如你所说的那样) - 上下文管理器是什么对于!一个简单的例子......:

import contextlib

@contextlib.contextmanager
def retry_forever(exception=ConnectionException, message='Connection lost. Press enter to try again'):
    while True:
        try: yield
        except exception:
            raw_input(message)
        else: break

现在,你可以使用

for url in urls:
    with retry_forever():
        downloadPage(url)

更好的变体(使用max#of retries,& c)可以优雅地重构为这种非常有用的形式。

答案 4 :(得分:0)

您可以使用retrying package

只需编写一个代码块,该代码块将在失败时不断重复,直到达到最大重试次数为止