2012-08-07 21 views
5

Wenn ich ein Python-Dekorateur Funktion wie diesePassing Parameter zur Laufzeit Dekorateur

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 

schaffe ich es, wie dieses

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

verwenden Aber ist es eine Möglichkeit, unterschiedliche Werte zu übergeben für ‚versucht 'und' Delay 'auf den Dekorator zur Laufzeit, so dass 20 und 30 Variablen sind?

+2

Der Dekorator wird zur Def-Zeit aufgerufen. Wenn Sie zur Laufzeit verschiedene Werte übergeben wollen, haben Sie einfach eine Funktion. Beispiel: 'def retry_until_true (func, tries, delay): ...'. –

Antwort

3

Sie eine Klasse als Dekorateur verwenden können, mit Instanzvariablen für tries und 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) 

Verbrauch:

@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

Sicher können Sie, nur Nest Funktionsdefinition in einer anderen Funktion, zum Beispiel:

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

Jedoch die cla ss Decorator Lösung ist praktischer.