如何使用一个类的实例变量作为在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()
有帮助吗?

解决方案

这不会工作;装饰器中的类创建时间,创建一个实例之前,其是所谓的长(如果有史以来发生)。所以,如果你的“装饰”所需要的情况下,你必须做的“装饰”在实例化时:

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()

请注意,根据它们的意义,我改变功能名称;实际的“装饰”,即该(潜在地)修改的方法中的功能,是在wrapper你的情况下,不decorator1

其他提示

您“整经机”功能实际上是一个装饰,而不是一个整经。您的“decorator1”功能是一个装饰构造。如果你想有机会获得self.var1在运行时,你必须做出一个整经机没有装饰:

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()

如果你想有更多的普通装饰,这是更好的主意来声明一个类调用:

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

使用:

  @decorator("var1")

被定义的类时,执行所述的装饰机,这样就可以不一个实例变量传递给它。

下面就是我们用来做这在往日。

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

    def method1(self):
        self.lock()
        try:
            self.do_method1()
        except Exception:
            pass # Might want to log this
        finally:
            self.unlock()

    def do_method1(self):
        print "method1"

    def lock(self):
        print "locking: %s" % self.arg1

    def unlock(self):
        print "unlocking: %s" % self.arg1

现在,子类只需要O强制do_method1获得“包装”的好处。做旧的方式,没有任何with声明。

是的,这是啰嗦。然而,它不涉及任何魔法,要么。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top