代码之家  ›  专栏  ›  技术社区  ›  Arun Kaliraja Baskaran

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

  •  3
  • Arun Kaliraja Baskaran  · 技术社区  · 7 年前

    我正在使用decorators来进行一些上下文管理,比如文件备份、恢复项目中的排序,并尝试使用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
          """
      

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

    1 回复  |  直到 7 年前
        1
  •  1
  •   BryceH    7 年前

    Passing parameters to decorator at runtime

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