【问题标题】:How to pass parameters to decorators at run-time?如何在运行时将参数传递给装饰器?
【发布时间】:2018-02-06 19:06:20
【问题描述】:

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

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

例如,我的课程如下所示:

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. 使装饰器不带任何参数,并使其在输入 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
        """
    

有没有更好的方法来解决这个问题?

【问题讨论】:

  • 一种方法是将def wrapper(*args,**kwargs): 更改为def wrapper(self, *args,**kwargs): 并使用self 参数来解析您的文件名。但是,这将使您的装饰器只能与您的特定类一起使用。
  • 是的,我同意..如果其他一些类将文件名存储在其他属性名中,那么它将无法工作.. :(
  • 第二个例子也可以在__init__self.performAction = copyAndRestoreFile(file=self.file)(self._actualActionCode)中实现

标签: python python-decorators


【解决方案1】:

例如,请看这里 - Passing parameters to decorator at runtime

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-17
    • 2018-05-30
    • 2016-02-14
    • 2021-11-21
    • 2018-08-24
    • 2014-10-01
    • 2018-06-07
    • 1970-01-01
    相关资源
    最近更新 更多