Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would one decorate an inherited method in the child class?

I'm not quite sure how to use a decorator on an inherited method. Normally decorators are put before the definition but for an inherited function the definition is given in the parent and not the child class. I would like to avoid rewriting the definition of the method in the child class and simply specify to put the decorator around the inherited method.

To make myself clearer, here is a working example of what I mean:

class Person():
    def __init__(self, age):
        self.age = age

    @classmethod
    def gets_drink(cls, ):
        print "it's time to get a drink!"
        return "A beer"

def dec(some_f):
    def legal_issue(obj,):
        some_f(obj)
        return 'A Coke'
    return legal_issue

class Child(Person):
    def __init__(self, age):
        Person.__init__(self, age=age)

    #in principle i'd like to write
    #@dec
    #self.gets_drink
    #which does not work
    #the only working way I found is by defining the method as a classmethod
    #and write this:

    @dec
    def gets_drink(self, ):
        return Person.gets_drink()

dad = Person(42)
son = Child(12)

print dad.gets_drink()
print son.gets_drink()

The way it is done in this example works, but it looks somehow weird to me, replacing the method with a call to the original method only to be able to put the decorator. Also, for this to work, the method needs to be defined as a classmethod in the parent class.

Am I missing something? How would experienced developers do this?

Any help, insights, critical comments and free coffees are much appreciated!

like image 262
jojo Avatar asked Jul 15 '14 21:07

jojo


People also ask

How do you decorate a classroom method?

To decorate a method in a class, first use the '@' symbol followed by the name of the decorator function. A decorator is simply a function that takes a function as an argument and returns yet another function. Here, when we decorate, multiply_together with integer_check, the integer function gets called.

What do child classes inherit?

Child classes inherit the methods of the parent class it belongs to, so each child class can make use of those methods within programs.

Can a parent inherit from a child class?

Inheritance concept is to inherit properties from one class to another but not vice versa. But since parent class reference variable points to sub class objects. So it is possible to access child class properties by parent class object if only the down casting is allowed or possible....

How do you call an inheritance parent class?

Using Classname: Parent's class methods can be called by using the Parent classname. method inside the overridden method. Using Super(): Python super() function provides us the facility to refer to the parent class explicitly. It is basically useful where we have to call superclass functions.


1 Answers

You don't have to use a decorator in decorator syntax. It is just a callable:

class Child(Person):
    def __init__(self, age):
        Person.__init__(self, age=age)

    gets_drink = dec(Person.gets_drink.__func__)

This adds the return value of the decorator to the child class as a method with the same name. The __func__ attribute unwraps the bound (class) method, retrieving the original function.

Note that your new method is now a regular method, not a classmethod, you'd have to re-wrap the result in a classmethod() call for that.

This works because the syntax

@decorator_expression
def function_definition():
    pass

is just syntactic sugar for:

def function_definition():
    pass
function_definition = decorator_expression(function_definition)
like image 143
Martijn Pieters Avatar answered Sep 22 '22 08:09

Martijn Pieters