Question

Donc, je pense que le code explique probablement ce que j'essaie de faire mieux que je ne peux le faire avec des mots, alors voici:

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

Le résultat:

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

J'essaie de faire en sorte que la classe mixin satisfasse aux exigences de la classe abstract / interface. Qu'est-ce qui me manque?

Était-ce utile?

La solution

L'héritage ne devrait-il pas être l'inverse? Dans le MRO, toto vient avant bar_for_foo_mixin , puis se plaint à juste titre. Avec class myfoo (bar_for_foo_mixin, foo) , cela devrait fonctionner.

Et je ne suis pas sûr que la conception de votre classe soit la bonne façon de le faire. Puisque vous utilisez un mixin pour implémenter bar , il pourrait être préférable de ne pas dériver de foo et de simplement l'enregistrer avec la classe 'foo' (c'est-à-dire foo.register (myfoo) ) . Mais ce n’est que mon intuition.

Par souci d'exhaustivité, voici la documentation sur ABCs .

Autres conseils

Je pense (testé dans un cas similaire) que l'inversion des classes de base fonctionne:

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

donc dans mro (), il trouverait une version concrète de bar () avant de trouver la version abstraite. Aucune idée si c'est ce qui se passe réellement en arrière-plan.

A bientôt, Lars

PS: le code qui a fonctionné dans Python 2.7 (python 3 utilise une méthode différente pour définir les métaclasses):

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()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top