嵌套类装饰器,它也是描述符类

时间:2019-03-11 03:00:21

标签: python python-3.x python-decorators python-descriptors

我遇到需要使用如下嵌套装饰器的情况,

class A(object):
    def __init__(self,v):
        print("A.init")
    @deco1
    @deco2
    def m(self, a):
        print("A.m")

装饰器的实现方式如下

class deco1(object):
    def __init__(self, f):
        print("deco1.init")
        self.f = f
    def __call__(self, *args, **kwargs):
        print("deco1.call.before")
        r = self.f(*args, **kwargs)
        print("deco1.call.after")
        return r
    def __get__(self, o, c):
        print("deco1.get")
        return MethodType(self, o)

class deco2(object):
    def __init__(self, f):
        print("deco2.init")
        self.f = f
    def __call__(self, *args, **kwargs):
        print("deco2.call.before")
        r = self.f(*args, **kwargs)
        print("deco2.call.after")
        return r
    def __get__(self, o, c):
        print("deco2.get")
        return MethodType(self, o)

问题是未调用deco2类的描述符方法,我需要调用该方法。 当我执行以下操作时,

aa = A(100)
aa.m(10)

实际

deco1.get
deco1.call.before
deco2.call.before
A.m
deco2.call.after
deco1.call.after

期望

deco1.get
deco1.call.before
deco2.get   #deco2.__get__ to be called
deco2.call.before
A.m
deco2.call.after
deco1.call.after

出于某种原因,我需要使用单独的装饰器。考虑到这一点,我该如何进行这项工作?另外,如果有人可以解释为什么不调用deco2。 get ,那就太好了!谢谢。

使用Python 3.7.x

1 个答案:

答案 0 :(得分:0)

创建装饰的m时,

deco2.get被调用一次。

装饰

@deco1
@deco2
def m

可以改写为

m = deco1(deco2(m))

因此,当计算deco1参数时,就会调用deco2.get。