Python:如何在遇到超时时再试一次

时间:2013-09-17 01:40:51

标签: python try-catch

我有一个连接到服务器的python程序发送一些命令,但是我发现这个错误

TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

在以前的这种情况中,我会使用类似的东西

try:
            do something
        except KeyError:
            do something else

我可以在同样的情况下做同样的事情,即

try:
                do something
            except TimeoutError:
               do something again

如果是这样,除了TimeoutError之外我该怎么做?我会再次做同样的命令吗?

4 个答案:

答案 0 :(得分:12)

  

我能否在同样的情况下做同样的事情

是的!您可以将try / except用于任何例外,TimeoutError并不特别。

  

如果是这样,除了TimeoutError之外我该怎么做?我会再次做同样的命令吗?

如果您只想重试一次,并将第二次超时计为真正的错误,则:是:

try:
    do something
except TimeoutError:
    do something

(如果“做某事”不仅仅是一个简单的陈述,你可能想要分解代码,这样你就不会重复了。)

但是,如果要多次重试,可能需要循环:

for _ in range(max_retries):
    try:
        do something
        break
    except TimeoutError:
        pass

您可能希望向else添加for子句以区分这两种情况(成功,并执行break,从未成功,只是用完了尝试)


由于此处的想法通常是处理可能出现的瞬态错误,因此您可能还需要添加其他内容,例如:

  • max_retries之后重新提出错误或提出另一个错误。
  • 以逐步更高的级别记录(例如,针对单个故障的调试消息,但是对“max_retries”的警告)。
  • 以指数退避重试(等待1秒,然后是2,4,8,......)。
  • 将URL推送到工作队列的末尾,而不是立即重试。如果您还需要(URL, retry_count)逻辑,则可以使用max_retries对,如果您还需要指数退避,则可以使用(URL, timestamp)对,如果您想要两者,则可以使用两者。 (当然,这只有在你不关心回复的顺序时才有效,或者可以在最后重新排序。)
  • 不同异常的不同规则(例如,500,502,503和504错误都可能由服务器或代理上的过载引起,但最佳重试逻辑可能不同 - 2018年的最佳启发式可能不同从2010年或2025年)。

对于复杂的组合,重试装饰器(如the one linked中的jterrace's helpful answer)是结束行为的好方法。

答案 1 :(得分:6)

您可以像上面提到的那样捕获TimeoutError:

import socket
import sys
try:
  dosomething()
except socket.TimeoutError:
  print >> sys.stderr, 'Retrying after TimeoutError'
  dosomething()

您还可以在函数上使用retry decorator pattern

@retry(socket.TimeoutError)
def dosomething():
    # code that causes a TimeoutError
    ...

答案 2 :(得分:1)

def f():
    pass #insert code here

错误后重复一次:

try:
    f()
except TimeoutError:
    f()

或循环直到成功:

while True:
    try:
        f()
        break
    except TimeoutError:
        pass

或数量有限:

attempts = 3
while attempts:
    try:
        f()
        break
    except TimeoutError:
        attempts -= 1

答案 3 :(得分:0)

请运行每个示例,它们已准备就绪!

示例1

import sys

try:
    incorrect.syntaxThatIJustMadeUP()
except:
    print((sys.exc_info()[0])) #Now you know what to except and CATCH
else:
    print("You will never see this message")

示例2

import sys

try:
    incorrect.syntaxThatIJustMadeUP()
except NameError:
    print("There is a problem with your SYNTAX Dude!")
except:
    print((sys.exc_info()[0])) #Incase another uncontrollable network problem occurs, User rages-Snaps IJ45
else:
    print("You will never see this message unless TRY suceeds")
    print("Why not put this try in a loop")