Pergunta

Então, eu acho que o código provavelmente explica o que estou tentando fazer melhor do que eu em palavras, então aqui vai:

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()

O resultado:

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

Eu estou tentando obter a classe mixin para satisfazer os requisitos da classe de interface / resumo. O que eu estou ausente?

Foi útil?

Solução

não deve a herança ser o contrário? No foo MRO atualmente vem antes bar_for_foo_mixin, e depois legitimamente reclama. Com class myfoo(bar_for_foo_mixin, foo) ele deve funcionar.

E eu não estou certo se o seu design de classe é o caminho certo para fazê-lo. Desde que você use um mixin para a implementação bar talvez seja melhor não derivam de foo e apenas registrá-lo com a classe 'foo' (ou seja foo.register(myfoo)). Mas esta é apenas a minha intuição.

Para completar, aqui é o href="http://docs.python.org/library/abc.html" rel="noreferrer"> documentação .

Outras dicas

eu acho que (testado em caso similar) que reverter os baseclasses funciona:

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

-lo no MRO () seria encontrar uma versão concreta de bar () antes de encontrar o abstrato. Não faço ideia se isso é realmente o que acontece no fundo embora.

Cheers, Lars

PS: o código que trabalhou em python 2,7 (python 3 tem uma maneira diferente de metaclasses set) foi:

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()
scroll top