2012-08-07 62 views
5

裝飾機如果我創建這樣參數傳遞到運行時

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 

一個Python裝飾功能,我可以用它像這樣

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

但是,有沒有辦法通過不同的值「嘗試'和'延遲'在運行時裝飾,所以20和30是變量?

+2

裝飾者在def時間被調用。如果你想在運行時傳遞不同的值,爲什麼不只是有一個函數。例如:'def retry_until_true(func,try,delay):...'。 – 2012-08-07 23:23:38

回答

3

你可以使用一個類作爲裝飾,以實例變量triesdelay

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) 

用法:當然

@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

可以,在其他功能只是嵌套函數定義,例如:

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

但是,cla ss裝飾者解決方案更實用。

相關問題