Frage

Warum ist das:

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

in Ordnung und funktioniert wie erwartet:

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

Aber diese:

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

Ist das nicht in Ordnung, und sprengt so:?

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
War es hilfreich?

Lösung

Es ist nicht ein custom-Metaklasse Problem (obwohl es sich Diagnose in metaclass Stufe):

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

, und das Problem ist nur das gleiche wie diese:

>>> 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
.

das heißt, kann nicht mehrfach erben von einer Basisklasse von einer abgeleiteten Klasse gefolgt - es ist unmöglich, eine konsistente MRO zu definieren, dass erfüllt die üblichen MRO Zwänge / Garantien

.

Zum Glück, die Sie nicht will zu tun, dass - die Unterklasse vermutlich eine Methode der Basisklasse überschreibt (das ist, was normale Subklassen tun ;-), und mit der Basisklasse „vor“ würde bedeuten, „die Überschreibung Shadowing weg“.

Setzen Sie die Basisklasse nach die abgeleitete ein ziemlich nutzlos ist, aber zumindest ist es harmlos (und im Einklang mit normalen MRO Garantien).

Ihr erstes Beispiel natürlich funktioniert, weil MyMixin ist nicht von list abgeleitet:

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

... aber es is von object abgeleitet (wie alle modernen Stil Python-Klasse), so das zweite Beispiel nicht arbeiten kann (ganz unabhängig von MyMixin eine benutzerdefinierte metaclass mit).

Andere Tipps

Hier legen Sie die übergeordneten Klasse erben, und die Elternklasse ist bereits eine andere Klasse zu erben, so gibt es keine Notwendigkeit, um die Klasse zu erben, dass die übergeordnete Klasse bereits vererbt.

Zum Beispiel:

class A(object):
.
.
class B(object, A):
.
.

Es wird einen Fehler werfen, weil A die Klasse Object erbt und B die A erbt, so indirekt B Objekt erbt, so gibt es keine Notwendigkeit zu vererben Objekt ist. . . .

Die Lösung ist nur die Objektklasse entfernen Klasse B ... Argumente Liste.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top