2016-04-26 93 views
2

我想擴展一個模塊中的類層次結構。在Python中擴展類層次結構

要擴展的模塊看起來像這樣。 模塊FOO:

class bar(object): pass 
class spam(bar): pass 
class eggs(bar): pass 

現在我想擴展這些類:使用

class my_bar(foo.bar): 
    def new_func(): pass 
class my_spam(foo.spam): pass 
class my_eggs(foo.eggs): pass 

在my_bar這樣做,一個新的功能new_func()不會在my_spam實例可

my_spam_instance.new_func() 

什麼是最好的(「最pythonic」)的方式來實現這一目標?我想到了多重繼承,像這樣:

class my_bar(foo.bar): pass 
class my_spam(foo.bar, my_bar): pass 
class my_eggs(foo.eggs, my_bar): pass 

雖然我從來沒有真正使用它,但我不確定這是最好的方法。

+0

你寫的東西應該可以工作,但是「鑽石關係」(my_spam繼承自foo.bar和my_bar,都是從bar繼承的)會使事情變得難以理解。你可以讓my_bar不從foo.bar(mixin)繼承。你可以給你想要擴展的類提供一些背景嗎? – syntonym

+0

根據你在這裏提供的細節,多重繼承(MI)應該對你有用。 – thebjorn

回答

0

你甚至都不需要從bar

Python的將增加的Mixin,這實際上是一個基類繼承my_bar,但沒有繼承

class NewFuncMixin(): 
    def new_func(): pass 

並將其添加到新的類

class my_bar(foo.bar, NewFuncMixin): pass 
class my_spam(foo.spam, NewFuncMixin): pass 
class my_eggs(foo.eggs, NewFuncMixin): pass 
+0

這聽起來不錯。但是,如何在my_spam .__ init __()中調用foo.spam和NewFuncMixin中的__init__方法?我可以使用super(),還是必須顯式調用它們(如foo.spam .__ init __()和NewFuncMixin .__ init __())? – Credics

+0

如果派生類沒有它,只會自動調用第一個'__init__'。所以基本上你可以在衍生'__init__'中明確地調用它: '''NewFuncMixin .__ init __(self,* args,** kwargs)'''' – aershov

0

怎麼樣一個mixin類?該模式是

class My_mixin(object): 
    def new_func(self): pass 

class My_spam(My_mixin, foo.spam): pass 
class My_eggs(My_mixin, foo.eggs): pass 

混入應該從對象繼承,並繼續繼承列表中,這樣的混合類方法得到優先名的左側。在mixin中,你可以包裝任何超類的方法:

class My_mixin(object): 

    def bar_method(self): 
     # stuff 
     bar_result = super(My_mixin, self).bar_method() 
     # more stuff 
     return bar_result # or my_result based on bar_result 

你當然可以完全覆蓋該方法,而不是包裝它。