2013-03-08 159 views
3

比方說,我有一個類如何從Python中重寫的@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。這可以做到嗎?

注意:該示例已被簡化,因爲我的具體示例涉及更多。假設我的目標不是連接字符串。

+0

這是蟒蛇2或3?如果2,你是從'object'繼承嗎? – 2013-03-08 10:03:51

+0

我很困惑你的使用子類作爲實例。他們根本不是一回事。 – 2013-03-08 10:05:08

+0

@Martjin:python 2,繼承對象。修復示例。 – 2013-03-08 10:07:21

回答

7

使用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)' 
+0

我可以使我的派生類的類方法將打印自己的類名(不是實例的類名)的類? 我的意思是'A2 = AdvancedGenerator2(AdvancedGenerator)A2.get_description()'並返回:'AdvancedGenerator2 AdvancedGenerator SimpleGenerator'? – Crusader 2017-03-22 21:31:42

+0

@Crusader:你的意思是你想要MRO中所有類的名字? 'return''.join([c .__ name__ for c in cls .__ mro __])'。 – 2017-03-23 09:49:23

+0

不,我的意思是如何在類樹中的某處獲取當前類變量。示例類:Grandparent-> Parent-> Child,每個類都有一些類var'test',我需要獲得所有這些變量的concat。在其他語言中,我可以這樣做'result = self.var + super()。get_var()' – Crusader 2017-03-24 13:20:56

相關問題