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

9avjhtql  于 2023-02-21  发布在  Python
关注(0)|答案(2)|浏览(156)

我有一个类,在函数上有一个单调的重复模式,我想把这个模式变成一个装饰器,但是这个装饰器必须访问当前示例的一些属性,所以我想把它变成这个类的一个方法,我遇到了一些问题。
这和我想要的很相似

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方法,但是我不知道如何使用当前示例中的方法作为修饰器。
有简单的方法吗?
EDIT:好的,答案很明显。正如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
uklbhaso

uklbhaso1#

装饰器只得到一个参数-它装饰的函数或方法。它没有得到作为self参数传递的示例-在装饰器被调用的那一刻,甚至类还没有被创建,更不用说类的示例了。示例将作为第一个参数传递给装饰的函数。因此您应该将self作为第一个参数包含在call()的参数列表中。
我看不出有必要在类作用域中包含装饰器,你可以这样做,但是你也可以把它放在模块作用域中。

hkmswyz6

hkmswyz62#

在装饰器必须设置对象中的属性的情况下,例如,向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

在本例中selfcall函数接收self
就我个人而言,我更喜欢将装饰器包含在类中,因为它对特定属性进行操作,看起来更加独立。

相关问题