2012-08-07 20 views
5

Si creo una función de Python decorador como estoPaso de parámetros a decorador en tiempo de ejecución

def retry_until_true(tries, delay=60): 
    """ 
    Decorator to rety a function or method until it returns True. 
    """ 
    def deco_retry(f): 
     def f_retry(*args, **kwargs): 
      mtries = tries 
      rv = f(*args, **kwargs) 
      while mtries > 0: 
       if rv is True: 
        return True 
       mtries -= 1 
       time.sleep(delay) 
       rv = f(*args, **kwargs) 
      return False 
     return f_retry 
    return deco_retry 

puedo utilizar de esta manera

@retry_until_true(20, delay=30) 
    def check_something_function(x, y): 
     ... 
     return True 

pero hay una manera de pasar valores diferentes para los 'intentos 'y' retrasar 'al decorador en tiempo de ejecución, de modo que 20 y 30 son variables?

+2

Se llama al decorador en el momento de la desinfección. Si desea pasar diferentes valores en tiempo de ejecución, ¿por qué no solo tiene una función? Por ejemplo, 'def retry_until_true (func, tries, delay): ...'. –

Respuesta

3

Se puede utilizar una clase como un decorador, con variables de instancia para tries y delay:

class RetryUntilTrue(object): 
    def __init__(self, f=None, tries=10, delay=30): 
     self.f = f 
     self.tries = tries 
     self.delay = delay 

    def __call__(self, *args, **kwargs): 
     if self.f is None: 
      self.f = args[0] 
     else: 
      tries = self.tries 
      while tries: 
       if self.f(*args, **kwargs): 
        return True 

       tries -= 1 
       time.sleep(self.delay) 

Uso:

@RetryUntilTrue 
def foo(x): 
    pass 

foo.tries = 20 
foo.delay = 1 

@RetryUntilTrue(tries=100, delay=9999) 
def bar(x): 
    pass 

bar.tries -= 1 
bar.delay = foo.delay 
1

Claro que puedes, simplemente nido definición de su función en otra función, por ejemplo:

def explicit_setup_func(tries, delay=60): 
    @retry_until_true(tries, delay) 
    def check_something_function(x, y): 
     # Code 

Sin embargo, la cla La solución decorativa ss es más práctica.

Cuestiones relacionadas