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ローカル変数'delay'(行xのスコープを囲むことで定義)

これは私にはまったく意味がありません。delay 値が割り当てられており、私はおそらくそれを私が好きなように参照できるはずです。誰かがエラーが何であるかを説明できますか、そして合理的であれば、どうすればそれを修正できますか?

4

1 に答える 1

5

このコードを実行しようとすると、実際にはクラッシュします。wrapped問題は、 (およびwrapper)のようなネストされたスコープでは、外部変数を読み取ることはできますが、それらに割り当てることはできないということです。

これが3.xnonlocalキーワードの目的です(これにより、への1回の呼び出しからのdelayすべての「インスタンス」で増加します)。これを2.xで複製するには、のようなことをして、としてアクセスする必要があります。wrappedretrydelay_lst = [delay]delay_lst[0]

変更をローカルにする場合はwrapped、新しい変数を作成し、値を.で初期化しますdelay

于 2012-07-30T20:23:21.453 に答える