2

我正在开发一个装饰器,它将重试运行一个函数最多 N 次,如下所示:

def retry(exceptions, truncate=5, delay=0.25):                                     
      """Retry the decorated function using an exponential backoff strategy.         
      If the function does not complete successfully a TimeoutException is           
      raised."""                                                                     
      def wrapper(func):                                                             
          @wraps(func)                                                               
          def wrapped(*args, **kwargs):                                              
              tries = 0                                                              
              while tries < truncate:                                                
                  try:                                                               
                      return func(*args, **kwargs)                                   
                  except exceptions, e:                                              
                      print "%s, Retrying in %d seconds..." % (str(e), delay)        
                      time.sleep(delay)                                              
>>                    delay += delay                                                 
                      tries += 1                                                     
              else:                                                                  
                  raise TimeoutException()                                           
          return wrapped                                                             
      return wrapper

对我来说,代码看起来很合理,但在突出显示的 pyflakes 抱怨的行上,报告:

赋值前引用的 W804 局部变量“延迟”(在第 x 行的封闭范围中定义)

这对我来说完全没有意义。delay 已经被分配了一个值,我想我应该可以随意引用它。有人可以解释错误是什么,如果合理,我该如何解决?

4

1 回答 1

5

如果您尝试运行此代码,它实际上会崩溃。问题在于,在wrapped(and wrapper) 等嵌套范围内,您可以读取外部变量但不能分配给它们。

这就是3.x 中nonlocal关键字的用途(这将增加从单个调用到delay的所有“实例” )。要在 2.x 中复制它,您需要执行类似的操作并将其作为.wrappedretrydelay_lst = [delay]delay_lst[0]

如果您希望修改是本地的wrapped,只需创建一个新变量并使用 的值对其进行初始化delay

于 2012-07-30T20:23:21.453 回答