如何从重写的@classmethod调用父类的@classmethod?
假设我有一个类
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
现在我把上面每个类都扩展了一下,变成了每个类都有具体实现的样子:
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
现在假设我调用了
SpaceShuttleGenerator.get_description()
问题是,在 AdvancedGenerator
里,我想调用 SimpleGenerator
里的一个方法,并且传入一个类的实例,具体来说是 SpaceShuttleGenerator
。这样做可以吗?
注意:这个例子是简化过的,因为我的实际例子要复杂得多。假设我的目标不是简单地拼接字符串。
1 个回答
17
使用 super()
:
@classmethod
def get_description(cls):
desc = super(AdvancedGenerator, cls).get_description()
return desc + ' Advanced(tm) ' + cls.adv_feature
使用 SimpleGenerator.get_description()
和 super(AdvancedGenerator, cls).get_description()
的区别在于 cls
的值会不同。当你直接调用类的时候,cls
会被设置为 SimpleGenerator
;而使用 super()
的时候,cls
会指向 AdvancedGenerator
。
比较一下你的代码(调整后使用 __name__
来说明这个区别):
>>> 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)'
以及使用 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)'