Вложенные декораторы классов, которые также являются классами дескрипторов - PullRequest
4 голосов
/ 11 марта 2019

У меня есть ситуация, когда мне нужно использовать вложенные декораторы, как показано ниже,

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 isn 'Тебя зовут, и я требую, чтобы его звали.Когда я делаю что-то вроде ниже,

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

Iнужно иметь отдельные декораторы по причине.Имея это в виду, как я мог сделать эту работу?Также, если кто-то может объяснить, почему deco2. get не вызывается, это было бы здорово!Спасибо.

Использование Python 3.7.x

1 Ответ

0 голосов
/ 11 марта 2019

deco2.get вызывался [один раз] при создании декорации m.

Декорацию

@deco1
@deco2
def m

можно переписать как

m = deco1(deco2(m))

поэтому при вычислении аргумента deco1 вызывался deco2.get.

...