classe abstrata + mixin + herança múltipla em python
-
05-07-2019 - |
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?
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()