Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a parent class's @classmethod from an overridden @classmethod in Python?

Let's say I have a class

class SimpleGenerator(object):
    @classmethod
    def get_description(cls):
        return cls.name

class AdvancedGenerator(SimpleGenerator):
    @classmethod
    def get_description(cls):
        desc = SimpleGenerator.get_description() # this fails
        return desc + ' Advanced(tm) ' + cls.adv_feature

Now I have extended each of the above classes to have a concrete one of each:

class StringGenerator(SimpleGenerator)
    name = 'Generates strings'
    def do_something():
        pass

class SpaceShuttleGenerator(AdvancedGenerator)
    name = 'Generates space shuttles'
    adv_feature = ' - builds complicated components'
    def do_something():
        pass

Now let's say I call

SpaceShuttleGenerator.get_description()

The issue is that in AdvancedGenerator I want to call the method in SimpleGenerator passing along an instance of the class, specifically SpaceShuttleGenerator. Can this be done?

NOTE: The example is simplified, as my concrete example is more involved. Let's say that my goal is not to concatenate strings.

like image 995
Krystian Cybulski Avatar asked Mar 08 '13 10:03

Krystian Cybulski


People also ask

How do I call a parent class's method from a child class in Python?

Calling Parent class Method Well this can done using Python. You just have to create an object of the child class and call the function of the parent class using dot(.) operator.

Can a parent class inherit from a child class Python?

Child or subclasses are classes that will inherit from the parent class. That means that each child class will be able to make use of the methods and variables of the parent class.

Can you call a parent class method from child class object?

Use the super keyword to access parent class method It should be used if the child class contains the same method as the parent class. In other words, the super keyword is used if the method is overridden. You override a method in the parent class by calling the same method in the child class.

How do you call a method overridden in Python?

In Python method overriding occurs by simply defining in the child class a method with the same name of a method in the parent class. When you define a method in the object you make this latter able to satisfy that method call, so the implementations of its ancestors do not come in play.


1 Answers

Use super():

@classmethod
def get_description(cls):
    desc = super(AdvancedGenerator, cls).get_description()
    return desc + ' Advanced(tm) ' + cls.adv_feature

The difference between using SimpleGenerator.get_description() and super(AdvancedGenerator, cls).get_description() is what cls will be set to. When calling the class directly, cls is set to SimpleGenerator, using super(), cls will refer to AdvancedGenerator.

Compare your code (adjusted to use __name__ to illustrate the difference):

>>> class SimpleGenerator(object):
...     @classmethod
...     def get_description(cls):
...         return cls.__name__
... 
>>> class AdvancedGenerator(SimpleGenerator):
...     @classmethod
...     def get_description(cls):
...         desc = SimpleGenerator.get_description() 
...         return desc + ' Advanced(tm)'
... 
>>> AdvancedGenerator.get_description()
'SimpleGenerator Advanced(tm)'

and using super():

>>> class AdvancedGenerator(SimpleGenerator):
...     @classmethod
...     def get_description(cls):
...         desc = super(AdvancedGenerator, cls).get_description()
...         return desc + ' Advanced(tm)'
... 
>>> AdvancedGenerator.get_description()
'AdvancedGenerator Advanced(tm)'
like image 167
Martijn Pieters Avatar answered Nov 15 '22 19:11

Martijn Pieters