Python中的抽象类 + 混入 + 多重继承
我觉得代码可能比我用语言解释得更清楚,所以我直接上代码:
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
我想让这个混合类满足抽象类或接口类的要求。我缺少了什么呢?
2 个回答
1
我觉得(在类似的情况下测试过)反转基类是有效的:
class myfoo(bar_for_foo_mixin, foo):
def __init__(self):
print "myfoo __init__ called"
self.bar()
这样在 mro() 中,它会先找到 bar() 的具体实现,而不是抽象的那个。不过我不确定这在后台到底是怎么运作的。
谢谢,Lars
附注:在 Python 2.7 中有效的代码(Python 3 有不同的方式来设置 metaclass)是:
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()
32
难道继承的顺序不应该反过来吗?在这个方法解析顺序(MRO)中,foo
现在排在 bar_for_foo_mixin
之前,所以它才会抱怨。用 class myfoo(bar_for_foo_mixin, foo)
这样写应该就能正常工作了。
而且我不太确定你的类设计是不是正确的。因为你用一个混入类来实现 bar
,可能不需要从 foo
继承,直接把它注册到 'foo' 类里会更好(也就是 foo.register(myfoo)
)。不过这只是我个人的感觉。
为了完整起见,这里有关于 ABC 的 文档链接。