Domanda

Quindi, penso che il codice probabilmente spieghi cosa sto cercando di fare meglio di quanto posso in parole, quindi ecco qui:

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

Il risultato:

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

Sto cercando di ottenere la classe mixin per soddisfare i requisiti della classe abstract / interface. Cosa mi sto perdendo?

È stato utile?

Soluzione

L'eredità non dovrebbe essere al contrario? Nel MRO foo viene attualmente prima bar_for_foo_mixin , e quindi si lamenta giustamente. Con class myfoo (bar_for_foo_mixin, foo) dovrebbe funzionare.

E non sono sicuro che il tuo design di classe sia il modo giusto per farlo. Dato che usi un mixin per implementare bar potrebbe essere meglio non derivare da foo e registrarlo semplicemente con la classe 'foo' (es. foo.register (myfoo) ) . Ma questo è solo il mio istinto.

Per completezza, ecco la documentazione per ABC .

Altri suggerimenti

Penso (testato in un caso simile) che invertire le basi funziona:

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

quindi in mro () troverà una versione concreta di bar () prima di trovare quella astratta. Non ho idea se questo sia effettivamente ciò che accade in background.

Saluti, Lars

PS: il codice che funzionava in python 2.7 (python 3 ha un modo diverso di impostare le metaclasse) era:

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()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top