Абстрактный класс + миксин + множественное наследование в Python - PullRequest
18 голосов
/ 05 мая 2009

Итак, я думаю, что код, вероятно, объясняет то, что я пытаюсь сделать лучше, чем могу, словами, вот так:

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 ]

17 голосов
/ 05 мая 2009

Разве наследство не должно быть наоборот? В MRO foo в настоящее время предшествует bar_for_foo_mixin, а затем по праву жалуется. С class myfoo(bar_for_foo_mixin, foo) должно работать.

И я не уверен, что ваш классный дизайн - верный способ сделать это. Поскольку вы используете mixin для реализации bar, может быть, лучше не наследовать от foo и просто зарегистрировать его в классе 'foo' (т.е. foo.register(myfoo)). Но это только мое внутреннее чувство.

Для полноты вот документация для азбуки .

0 голосов
/ 06 сентября 2013

Я думаю (проверено в аналогичном случае), что реверсирование базовых классов работает:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...