26

我有一个类在他们的功能上有一个沉闷的重复模式,我想把这个模式变成一个装饰器。但问题是这个装饰器必须访问当前实例的一些属性,所以我想把它变成这个类中的一个方法。我有一些问题。

所以,这类似于我想要的:

class DullRepetitiveClass:
    def __init__(self, nicevariable):
        self.nicevariable = nicevariable

    def mydecorator(self, myfunction):
        def call(*args, **kwargs):
            print "Hi! The value of nicevariable is %s"%(self.nicevariable,)
            return myfunction(*args, **kwargs)
        return call

    @mydecorator            #Here, comment (1) below.
    def somemethod(self, x):
        return x + 1

(1) 问题来了。我想用DullRepetitiveClass.mydecorator方法来装饰somemethod方法。但我不知道如何使用当前实例中的方法作为装饰器。

有没有一种简单的方法可以做到这一点?

编辑:好的,答案很明显。正如 Sven 在下面所说,装饰器本身只是转换方法。方法本身应该处理与实例有关的所有事情:

def mydecorator(method):
    def call(self, *args, **kwargs):
        print "Hi! The value of nicevariable is %s"%(self.nicevariable,)
        return method(self, *args, **kwargs)
    return call


class DullRepetitiveClass:
    def __init__(self, nicevariable):
        self.nicevariable = nicevariable

    @mydecorator            
    def somemethod(self, x):
        return x + 1
4

1 回答 1

18

装饰器只得到一个参数——它所装饰的函数或方法。它没有将实例作为self参数传递——在调用装饰器的那一刻,甚至还没有创建类,更不用说类的实例了。该实例将作为第一个参数传递给修饰函数,因此您应该将self其作为第一个参数包含在call().

我认为没有必要在类范围中包含装饰器。您可以这样做,但您也可以在模块范围内使用它。

于 2012-07-31T13:01:46.727 回答