如何在Python中使用类实例变量作为方法装饰器的参数?

5 python decorator

如何在Python中使用类实例变量作为方法装饰器的参数?以下是一个最小的例子,显示了我正在尝试做的事情.它显然失败,因为装饰器函数无法访问实例的引用,我不知道如何从装饰器访问引用.

def decorator1(arg1):
    def wrapper(function):
        print "decorator argument: %s" % arg1
        return function
    return wrapper

class Foo(object):
    def __init__(self, arg1):
        self.var1 = arg1

    @decorator1(self.var1)
    def method1(self):
        print "method1"

foo = Foo("abc")
foo.method1()
Run Code Online (Sandbox Code Playgroud)

bal*_*pha 9

它不会起作用; 在类创建期间调用装饰器,这在创建实例之前很久(如果发生的话).因此,如果你的"装饰者"需要实例,你必须在实例化时进行"装饰":

def get_decorator(arg1):
    def my_decorator(function):
        print "get_decorator argument: %s" % arg1
        return function
    return my_decorator

class Foo(object):
    def __init__(self, arg1):
        self.var1 = arg1
        self.method1 = get_decorator(self.var1)(self.method1)

    def method1(self):
        print "method1"

foo = Foo("abc")
foo.method1()
Run Code Online (Sandbox Code Playgroud)

请注意,我根据其含义更改了函数名称; 实际的"装饰器",即(可能)修改方法的功能,wrapper在你的情况下,而不是decorator1.


Arp*_*ius 5

你的"warper"函数实际上是一个装饰者,而不是一个整经者.你的"decorator1"函数是一个装饰器构造函数.如果你想在运行时访问self.var1,你必须做一个warper而不是装饰器:

def decorator(function):
  def wrapper(self,*args,**kwargs):
    print "Doing something with self.var1==%s" % self.var1
    return function(self,*args,**kwargs)
  return wrapper

class Foo(object):
  def __init__(self, arg1):
    self.var1 = arg1

  @decorator
  def method1(self):
    print "method1"

foo = Foo("abc")
foo.method1()
Run Code Online (Sandbox Code Playgroud)

如果你想拥有更多的通用装饰器,最好是声明一个可调用的类:

class decorator:
  def __init__(self,varname):
      self.varname = varname
  def __call__(self,function):
    varname=self.varname
    def wrapper(self,*args,**kwargs):
      print "Doing something with self.%s==%s" % (varname,getattr(self,varname))
      return function(self,*args,**kwargs)
    return wrapper
Run Code Online (Sandbox Code Playgroud)

使用:

  @decorator("var1")
Run Code Online (Sandbox Code Playgroud)