2012-08-07 15 views
5

Se creo una funzione pitone decoratore come questoparametri Passando al decoratore in fase di esecuzione

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 

posso usare in questo modo

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

Ma c'è un modo per passare valori diversi per 'prove 'e' ritardare 'il decoratore in fase di runtime, in modo che 20 e 30 siano variabili?

+2

Il decoratore è chiamato in orario def. Se vuoi passare diversi valori in fase di esecuzione perché non avere solo una funzione. Es .: 'def retry_until_true (func, tries, delay): ...'. –

risposta

3

È possibile utilizzare una classe come decoratore, con le variabili di istanza per tries e 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) 

Usage:

@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

Certo che puoi, proprio nido definizione la funzione in un'altra funzione, ad esempio:

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

Tuttavia, il cla La soluzione per decoratori ss è più pratica.

Problemi correlati