2017-08-29 64 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

回答

相关问题