简体   繁体   中英

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM