【发布时间】: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
但正如您所见,文件名仅在我创建对象时才可用。那么如何解决此类问题。
我尝试了几个有效的解决方案:
-
使装饰器不带任何参数,并使其在输入 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。这就是我所看到的问题。 ..
-
在运行时装饰..
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)中实现