57 votes

incohérence d'héritage multiple de métaclasse

Pourquoi est-ce:

 class MyType(type):
    def __init__(cls, name, bases, attrs):
        print 'created', cls
class MyMixin:
    __metaclass__ = MyType
class MyList(list, MyMixin): pass
 

ok, et fonctionne comme prévu:

 created <class '__main__.MyMixin'>
created <class '__main__.MyList'>
 

Mais ça:

 class MyType(type):
    def __init__(cls, name, bases, attrs):
        print 'created', cls
class MyMixin:
    __metaclass__ = MyType
class MyObject(object, MyMixin): pass
 

Est-ce que ça ne va pas, et explose ainsi?

 created <class '__main__.MyMixin'>
Traceback (most recent call last):
  File "/tmp/junk.py", line 11, in <module>
    class MyObject(object, MyMixin): pass
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases object, MyMixin
 

83voto

Alex Martelli Points 330805

Ce n'est pas une coutume métaclasse problème (même si elle est diagnostiquée à métaclasse stade):

>>> class Normal(object): pass
... 
>>> class MyObject(object, Normal): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases object, Normal

et le problème est le même que celui-ci:

>>> class Derived(Normal): pass
... 
>>> class Ok(Derived, Normal): pass
... 
>>> class Nope(Normal, Derived): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases Normal, Derived

c'est à dire, ne peut pas se multiplier hériter d'une classe de base suivie par une classe dérivée-il est impossible de définir une constante MRO qui satisfait à l'habitude MRO contraintes/garanties.

Heureusement, vous n'avez pas envie de le faire -- la sous-classe, vraisemblablement, les remplacements d'une méthode de la classe de base (c'est ce normal sous-classes n';-), et d'avoir la classe de base "en face" signifierait "de l'ombre à la remplacer".

Mettre la classe de base après la dérivée est assez inutile, mais au moins il est inoffensif (et conforme à la normale MRO garanties).

Votre premier exemple de cours fonctionne parce qu' MyMixin est pas dérivé d' list:

>>> MyMixin.__mro__
(<class '__main__.MyMixin'>, <type 'object'>)

...mais il est dérivé d' object (comme à chaque style moderne Python classe), de sorte que le deuxième exemple, on ne peut pas travailler (tout à fait indépendamment de l' MyMixin ayant une coutume métaclasse).

-1voto

user3669108 Points 1

Ici, Vous hériterez:

La classe Parent et Parent de la classe déjà hériter d'une autre classe, DONC il n'est pas nécessaire pour hériter de la classe mère de la classe déjà hérité.

par exemple:

classe A(objet): . . classe B(objet, Un): . . Il lèvera une erreur, car Un hérite de la classe Object et B est d'hériter de l'Une, donc indirectement B hérite de l'objet, donc pas besoin d'hériter de l'objet, de . . . . La Solution est de supprimer la classe d'objet de la classe B ... les arguments de la liste ..

Merci,

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X