12 Stimmen

Metaklasse wird in Unterklassen nicht aufgerufen

Hier ist eine Python-Sitzung.

>>> class Z(type):
    def __new__(cls, name, bases, attrs):
        print cls
        print name
        return type(name, bases, attrs)
...     
>>> class Y(object):
    __metaclass__ = Z
...     
<class '__main__.Z'>
Y
>>> class X(Y):
...     pass
... 
>>> class W(Y):
...     __metaclass__ = Z
...     
<class '__main__.Z'>
W
>>> 

Nachdem ich die Klasse X definiert habe, erwarte ich, dass Z._new__ für sie aufgerufen wird und die zwei Zeilen gedruckt werden, was nicht geschieht (da Metaklasse vererbt werden?)

14voto

nikow Punkte 20645

Das Problem ist, dass die cls Argument (das Metaklassenobjekt) wird nicht weitergegeben, wenn Sie type daher das Klassenobjekt Y die erstellt und zurückgegeben wird, hat keinen Verweis auf die Metaklasse Z .

Wenn Sie die letzte Zeile in __new__ avec

return super(Z, cls).__new__(cls, name, bases, attrs)

dann funktioniert es. Beachten Sie, dass, obwohl cls wird verwendet in super müssen wir noch cls auch als Argument, da super gibt hier eine ungebundene Methode zurück (siehe ici für mehr).

Als Alternative zur Verwendung von Super könnte man verwenden:

 return type.__new__(cls, name, bases, attrs)

Das Wichtigste ist, dass wir die cls (unser Metaklassenobjekt Z ) zur Klassenmethode __new__ . Die kürzere Form type(name, bases, attrs) informiert type selbst für die cls Argument, das natürlich falsch ist. Dieser Fehler ist vergleichbar mit dem Aufruf einer Instanzmethode mit dem falschen self Argument.

Ich bevorzuge die Verwendung von super , da dies der bessere Stil ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X