2017-08-29 62 views
2

我正在使用裝飾器來做一些上下文管理,如文件備份,在我的項目中恢復排序,並嘗試使用裝飾器來達到這個目的。如何在運行時將參數傳遞給裝飾器?

但我不明白如何在運行時將參數傳遞給裝飾器。

例如我的類會是什麼樣子:

class myLogFileHandler: 
    def __init__(self,file): 
     self.file=file 
     return 

    @copyAndRestoreFile(file=<how-pass-self.file-here?>) 
    def performAction(**kwargs): 
     """ 
      do something 
     """ 

我的裝飾是:

def copyAndRestoreFile(file): 
    def dec(fn): 
     def wrapper(*args,**kwargs): 
      #copy file to temp... 
      fn(*args,**kwargs) 
      #restore file from temp... 
     return wrapper 
    return dec 

但正如你看到的文件名是availble的,只有當我創建了一個對象。那麼如何解決這些問題。

我試過幾個解決方案,它的工作:

  1. 做裝飾不帶任何參數,使它看起來在輸入ARGS字典中的特定變量..

    def copyAndRestoreFile(fn): 
        def dec(**kwargs,file): 
         #copy file to temp... 
         fn(*args,**kwargs) 
         #restore file from temp... 
        return dec 
    
    @copyAndRestoreFile 
    def performAction(**kwargs,file=self.file): 
        """ 
         do something 
        """ 
    

    用這種方法我不能讓裝飾器成爲任何一個可以使用的通用裝飾器..任何使用它的人都應該有一個文件arg來裝飾功能..那就是我看到的那個...

  2. 裝飾在運行時..

    def performAction(**kwargs): 
        copyAndRestoreFile(file=self.file)(self._actualActionCode)(**kwargs) 
    
    def _actualActionCode(**kwargs): 
        """ 
         do something 
        """ 
    

有沒有更好的辦法來解決這個問題?

+2

一種方法是將def包裝(* args,** kwargs):''轉換爲'def wrapper(self,* args,** kwargs):'並使用'self'參數來解析文件名。然而,這會讓你的裝飾器只能與你的特定類一起使用。 – Kendas

+0

是的,我同意..如果其他一些類存儲在其他屬性名稱的文件名,那麼它不會工作.. :( –

+0

第二個例子也可以在'__init__'中實現'self_performAction = copyAndRestoreFile(file = self .file)(self._actualActionCode)' – Kendas

回答

相關問題