如何在运行时将参数传递给装饰器?

时间:2017-08-29 10:48:49

标签: python python-decorators

我正在使用装饰器来执行一些上下文管理,例如文件备份,在我的项目中恢复排序并尝试使用装饰器来实现此目的。

但我不明白如何在运行时将参数传递给装饰器。

例如,我的课程看起来像:

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

但正如您所看到的,只有在我创建对象时,文件名才可用。那么如何解决这类问题呢。

我尝试了几种有效的解决方案:

  1. 使装饰器不带任何参数,并使其在输入参数字典中查找特定变量。

    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
        """
    
  3. 有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:1)

有关示例,请参阅此处 - Passing parameters to decorator at runtime

如果还有其他细节请澄清。