一个方法可以是同一个类的另一个方法的装饰器吗?

问题描述 投票:0回答:2

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

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

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
python instance decorator
2个回答
19
投票

装饰器只有一个参数——它装饰的函数或方法。它没有将实例作为

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

的参数列表中

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


0
投票

装饰器必须在对象中设置属性的情况,例如为

nicevariable
添加一个字符, 您可以自己设置装饰器,而不是依赖 Python 通过
@
运算符

提供的语法糖
class DullRepetitiveClass:
    def __init__(self, nicevariable):
        self.nicevariable = nicevariable
        self.somemethod = self.mydecorator(self.somemethod)

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

    def somemethod(self, x):
        return x + 1

注意

call
如何在其参数中没有获得
self
(如果您想检查,打印出
args
),但是对
myfunction(*args, **kwargs)
的调用确实注入了它,所以
somemethod
得到了它。

另一方面,如果你把装饰器放在类之外,你仍然可以访问对象:

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


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

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

在这种情况下

self
call
函数接收
self

就个人而言,我更喜欢将装饰器包含在类中,因为它对其特定属性进行操作并且看起来更独立。

© www.soinside.com 2019 - 2024. All rights reserved.