2016-03-22 4 views
2

が、私はそのような再試行メカニズムを使用している関数内でデコレータを使う:(exceptブロック/常に挑戦中)関数の内部

 def load(self): 
      [........] 
      # Retry mechanism for locking database 
      for i in range(1, max_connection_retries+1):       
       try: 
        cu.lock() 
        break 
       except LockError as l_error: 
        if i < max_connection_retries: 
         sleep(20) 
         continue 
        else: 
         raise ContinuableError (logger.console(datetime.now().time().strftime ("%b %d %H:%M:%S") + ' ERROR:Impossible to lock the database after %i retries' % max_connection_retries)) 
     [.......] 

私はの他の部分に数回、このメカニズムを使用しています同じ機能と他の機能で使用できます。コードのこの部分だけにデコレータを適用することは可能でしょうか?

 def load(self): 
      [.......] 
      @retry(max=5,message='blablabla')      
      try: 
       cu.lock() 
       break 
      except LockError as l_error: 

      [.......] 

      @retry(max=5)      
      try: 
       cu.unlock() 
       break 
      except LockError as l_error: 

もしそうなら、そのようなタスクを行うためのデコレータの例を私に教えてもらえますか?

+2

デコレータは機能のみで動作します。また、ここでメソッドを使用して、リトライパラメータを引数として渡すのはなぜですか?毎回同じコードを実行しようとしているようです。 –

+0

@KurtStutsman - 私はOPの特定のユースケースについてはわかりませんが、 'retry'部分がいくつかの関数で実行された古いコードを見てきました。再試行は基本的な機能( 'lock'、' unlock'、 'update'、' delete'など - データベースコマンドなど)。これは、 'maxRetries'で10個のメソッドを乱雑にするのではなく、' decorator'機能を使用するための完璧なユースケースのようです。それは、あなたの最初の文章にはスポットがあり、OPは何を進める必要があると言いました。 – dwanderson

答えて

3

デコレータ構文は、コードの無名ブロックを任意に適用することはできません

# f could be a class as well 
def f(): 
    ... 
f = retry(f) 

のためだけの構文糖です。デコレータの主な目的は名前を再バインドすることであり、無名ブロックには名前がありません。

あなたがする必要があるのは、装飾される関数にリトライしたいコードをリファクタリングすることです。例えば、

@retry(max=5, message='blablabla') 
def get_lock(): 
    try: 
     cu.lock() 
    except LockError as l_error: 
     # Some action dependent on the implementation of retry 


def load(self): 
    get_lock() 
+0

あなたの答えをありがとう、私はこのアプローチを試してみます – psagrera

1

としてはparamsはとしてその機能にデコレータは(messgemax等及び他のもの)機能のみに適用することができるが、別々の機能に「リトライ」ロジックを移動しcu.lock/cu.unlockを渡すことができます言いました:

def retry(func, tries, message): 
    for i in range(1, tries+1):       
     try: 
      func() # <- call passed function 
      break 
     except LockError as l_error: 
      if i < tries: 
       sleep(20) 
       continue 
      else: 
       raise ContinuableError('...') 

def load(self): 
    retry(cu.lock, tries=5, message='blablabla') # pass cu.lock to be called 

    retry(cu.unlock, tries=5, message='blablabla') # pass cu.unlock to be called 
関連する問題