Почему мне нужно повторить определение метода при использовании django.utils.decorators method_decorator в унаследованном классе - PullRequest
0 голосов
/ 04 марта 2012

Привет. Я пытаюсь понять, как декоратор django.utils.decorators method_decorator. Method_decorator превращает декоратор функции в декоратор метода класса.

Источник для этого декоратора находится в (https://github.com/django/django/blob/master/django/utils/decorators.py)

Мой пример функции декоратора:

def run_eight_times(myfunc):
    def inner_func(*args, **kwargs):
        for i in range(8):
            myfunc(*args, **kwargs)
    return inner_func

Мой пример базового класса:

class Myclass(object):

    def __init__(self,name,favorite_dish):
        self.name = name
        self.favorite_dish = favorite_dish

    def undecorated_function(self):
        print "%s likes spam in his favorite dish %s" % (self.name,self.favorite_dish)

Теперь я хочу создать унаследованный класс, который использует метод method_decorator django.utils.decorators для украшения метода Myclass undecorated_function. Чтобы заставить method_decorator работать, мне нужно переопределить функцию в унаследованном классе.

Так это работает:

class Myrepetitiveclass(Myclass):

    def __init__(self,*args, **kwds):
        Myclass.__init__(self,*args,**kwds)

    @method_decorator(run_eight_times)
    def undecorated_function(self):
        print "%s likes spam in his favorite dish %s" % (self.name,self.favorite_dish) 

noisier_me = Myrepetitiveclass("harijaynoisyclass","moreeggs")
noisier_me.undecorated_function()

Я немного запутался и не знаю, почему приведенный ниже код не работает и выдает синтаксическую ошибку.

Это интерпретируется неправильно и выдает синтаксическую ошибку.

class Myrepetitiveclass(Myclass):

    def __init__(self,*args, **kwds):
        Myclass.__init__(self,*args,**kwds)

    # Why does this not work? and gives a syntax error?

    @method_decorator(run_eight_times)
    self.undecorated_function

Как мне декорировать функцию в дочернем классе, не переопределяя ее?

1 Ответ

1 голос
/ 05 марта 2012

self не существует в этой области - он существует только внутри метода и только тогда, потому что он передается в качестве первого параметра.

Способ сделать это - переопределить метод и просто вызвать метод суперкласса:

@method_decorator(run_eight_times)
def undecorated_function(self):
    super(Myrepetitiveclass, self).undecorated_function() 

Кроме того, два комментария к вашему другому коду: нет смысла переопределять __init__ метод, если вы просто вызываете родительский метод, но если вам нужно, вы должны использовать super, как я это сделал здесь, вместо того, чтобы использовать имя самого суперкласса.

...