2016-04-26 149 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 

你当然可以完全覆盖该方法,而不是包装它。