python中的抽象类+ mixin +多重继承

时间:2009-05-05 17:10:44

标签: python abstract-class multiple-inheritance mixins

所以,我认为这段代码可能解释了我想要做的比我言语更好的事情,所以这里有:

import abc

class foo(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def bar(self):
        pass


class bar_for_foo_mixin(object):
    def bar(self):
        print "This should satisfy the abstract method requirement"


class myfoo(foo, bar_for_foo_mixin):
    def __init__(self):
        print "myfoo __init__ called"
        self.bar()

obj = myfoo()

结果:

TypeError: Can't instantiate abstract class myfoo with abstract methods bar

我正在尝试使用mixin类来满足abstract / interface类的要求。我错过了什么?

2 个答案:

答案 0 :(得分:17)

继承不应该反过来吗?在MRO foo目前位于bar_for_foo_mixin之前,然后正确地抱怨。使用class myfoo(bar_for_foo_mixin, foo)它应该有效。

我不确定你的班级设计是否是正确的做法。由于您使用mixin来实现bar,最好不要从foo派生并只使用'foo'类(即foo.register(myfoo))注册它。但这只是我的直觉。

为了完整性,这里是documentation for ABCs

答案 1 :(得分:0)

我认为(在类似情况下测试)反转基类有效:

class myfoo(bar_for_foo_mixin, foo):
    def __init__(self):
        print "myfoo __init__ called"
        self.bar()

所以在mro()中它会在找到抽象的之前找到bar()的具体版本。不知道这是否实际上是在后台发生的事情。

干杯,拉尔斯

PS:在python 2.7中工作的代码(python 3有不同的设置元类的方法)是:

class A(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def do(self):
        pass

class B(object):
    def do(self):
        print "do"

class C(B, A):
    pass

c = C()