Абстрактный класс + mixin + множественное наследование в 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
Я пытаюсь заставить класс mixin удовлетворять требованиям класса abstract/interface. Что мне не хватает?
Ответы
Ответ 1
Разве наследование не должно быть наоборот? В MRO foo
в настоящее время наступает до bar_for_foo_mixin
, а затем справедливо жалуется. С class myfoo(bar_for_foo_mixin, foo)
он должен работать.
И я не уверен, что ваш дизайн класса - это правильный способ сделать это. Поскольку вы используете mixin для реализации bar
, лучше не выводить из foo и просто регистрировать его с помощью класса "foo" (т.е. foo.register(myfoo)
). Но это только мое чувство кишки.
Для полноты, вот документация для ABC.
Ответ 2
Я думаю (проверено в аналогичном случае), что реверсирует работу базовых очков:
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()