Why do I need to repeat method definition while using django.utils.decorators method_decorator in inherited class

StackOverflow https://stackoverflow.com/questions/9557560

Question

Hi I am trying to understand the django.utils.decorators method_decorator decorator. The method_decorator turns a function decorator into a class method decorator.

The source for this decorator is at (https://github.com/django/django/blob/master/django/utils/decorators.py)

My example function decorator:

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

My example base class:

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)

Now I want to create an inherited class that uses the django.utils.decorators method_decorator to decorate the Myclass method undecorated_function. To get the method_decorator to work I need to redefine the function in the inherited class.

So This works:

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()

I am a little confused and dont know why the code below does not work and gives a syntax error.

This does not get interpreted correctly and gives a syntax error.

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

How do I decorate a function in the child class without redefining it?

Était-ce utile?

La solution

self doesn't exist in that scope - it only exists inside a method, and only then because it's passed as the first parameter.

The way to do this is to override the method, and simply call the super class method:

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

Also, two comments on your other code: there's no point overriding the __init__ method if you're just calling the parent method, but if you do need to that you should use super as I have done here, rather than using the name of the superclass itself.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top