TypeErrors Verwendung von Metaklassen in Verbindung mit Mehrfachvererbung
Ich habe zwei Fragen converning Metaklassen und mehrfache Vererbung. Die erste ist: Warum bekomme ich eine TypeError für die Klasse Derived
aber nicht für Derived2
?
class Metaclass(type): pass
class Klass(object):
__metaclass__ = Metaclass
#class Derived(object, Klass): pass # if I uncomment this, I get a TypeError
class OtherClass(object): pass
class Derived2(OtherClass, Klass): pass # I do not get a TypeError for this
Die genaue Fehlermeldung ist:
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution order (MRO) for bases object, Klass
Die zweite Frage ist: Warum tut super
Arbeit nicht in diesem Fall(wenn ich __init__
statt __new__
, super
wieder funktioniert):
class Metaclass(type):
def __new__(self, name, bases, dict_):
return super(Metaclass, self).__new__(name, bases, dict_)
class Klass(object):
__metaclass__ = Metaclass
Dort bekomme ich:
TypeError: Error when calling the metaclass bases type.__new__(X):
X is not a type object (str)
Ich bin mit Python 2.6.
InformationsquelleAutor nils | 2010-02-04
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die zweite Frage wurde schon gut beantwortet, zweimal, obwohl
__new__
ist eigentlich ein staticmethod, nicht eine classmethod, wie irrtümlich behauptet in einem Kommentar...:Die erste Frage (wie jemand erwähnt) hat nichts zu tun mit Metaklassen: Sie können nicht einfach multiplizieren Erben von zwei Klassen A und B in dieser Reihenfolge, wo B ist eine Unterklasse von A. E. g.:
MRO garantiert, dass ganz Links Basen besucht werden, vor rechten, aber auch garantiert, dass unter den Vorfahren, wenn x eine Unterklasse von y, dann ist x besucht, bevor y. Es ist unmöglich, um diese Garantien in diesem Fall. Es gibt einen guten Grund für diese garantiert natürlich: ohne Sie (z.B. im alten Stil-Klassen, die nur Garantie für die Links-rechts Reihenfolge, in der Methode, Auflösung, nicht der Unterklasse Einschränkung) alle überschreibungen in x würde ignoriert werden zu Gunsten der Definitionen in y, und das kann nicht so viel Sinn. Denken Sie daran: was hat es bedeutet, Sie zu beerben
object
erste, und aus einer anderen zweiten Klasse? Dassobject
's (im wesentlichen nicht existent;-) definition der verschiedenen speziellen Methoden muss Vorrang vor der anderen Klasse, wodurch die anderen Klasse überschreibt, um ignoriert zu werden?__new__
verwendbar ist w/osuper
- außer in komplexen Fällen von Mehrfachvererbung. Wenn Sie in komplexen mehrfach-Vererbung__new__
's vorsichtiger.Für die erste Frage, haben Sie einen Blick auf die Beschreibung von MRO in python - insbesondere der "schlechte Method Resolution order" Abschnitt. Im wesentlichen ist es mit der Tatsache zu tun, dass python nicht weiß, ob Objekt oder Klass Methoden. (Es ist nichts zu tun mit der Verwendung von Metaklassen.)
Für die zweite Frage an, wie es aussieht, sind Missverständnisse wie die
__new__
Funktion arbeitet. Es braucht nicht einen Verweis auf sich selbst als erstes argument - es nimmt einen Verweis auf den Typ der Klasse instanziiert wird. So Ihr code sollte wie folgt Aussehen:Für die zweite Frage, die man sich übergeben zu müssen, selbst zu
__new__
wie diese:Ich kann mich nicht erinnern aus der Spitze von meinem Kopf, warum das so ist, aber ich denke, es ist weil
type.__new__
ist nicht eine Methode gebunden und somit nicht wie von Zauberhand Holen Sie sich die self-argument.__new__
ist eine classmethod, nicht selbst da, es ist verwirrendcls
oder somesuch, aber ich war nach, was der original-poster verwendet.Warum würden Sie das tun?
Klass bereits leitet sich vom Objekt.
Ist Sinn der Sache hier.