python - Klassenattribute scheinbar nicht geerbt

9

In einem kürzlichen Projekt versuche ich etwas Ähnliches (komplexer, aber das gleiche Ergebnis):

%Vor%

Ich verstehe das:

%Vor%

Werden Klassenattribute nicht vererbt? Wenn ja, gibt es eine mögliche Lösung in einem ähnlichen Rahmen wie oben?

BEARBEITEN: Vielleicht ist es einfacher zu sehen, was ich meine, indem ich ein aktuelles (vereinfachtes) Beispiel aus dem Programm verwende.

%Vor%

Im Grunde genommen möchten Sie eine Funktion auf der Grundfarbe ausführen, um eine dunklere Farbe zu erzeugen, die in der Klasse gespeichert wird (mehrere Instanzen der Klasse wollen die gleiche Farbe, aber es wird eine längere Klassenhierarchie geben). Ich hoffe, das wird mehr Sinn machen.

    
thrstein 08.09.2012, 08:03
quelle

2 Antworten

3

Es soll diese nicht erben. Die Metaklasse empfängt die Attribute, die für die Klasse definiert sind, die sie instanziiert, nicht die ihrer Basisklassen. Der Hauptpunkt des Metaklassenkonstruktors besteht darin, Zugriff auf das zu bekommen, was tatsächlich im Klassenkörper angegeben ist.

Tatsächlich sind die Attribute der Basisklasse überhaupt nicht "in" der Unterklasse. Es ist nicht so, dass sie in die Unterklasse "kopiert" werden, wenn Sie sie definieren, und tatsächlich "weiß" die Unterklasse zur Erstellungszeit nicht einmal, welche Attribute ihre Oberklassen haben könnten. Wenn Sie auf B.foo zugreifen, versucht Python zuerst, das Attribut auf B zu finden. Wenn es nicht gefunden wird, sucht Python nach seinen Superklassen. Dies geschieht jedes Mal dynamisch, wenn Sie versuchen, ein solches Attribut zu lesen. Der Metaklassen-Mechanismus soll keinen Zugriff auf Attribute der Oberklasse haben, da diese in der Unterklasse nicht vorhanden sind.

Ein möglicherweise damit verbundenes Problem ist, dass Ihre Definition von __new__ falsch ist. Die Argumente für die Metaklasse __new__ sind cls, name, bases und attrs. Das dritte Argument ist die Liste der Basisklassen, nicht "Argumente" (was auch immer Sie beabsichtigen). Das vierte Argument ist die Liste der Attribute, die im Klassenkörper definiert sind. Wenn Sie Zugriff auf geerbte Attribute haben möchten, können Sie diese über die Basen abrufen.

Wie auch immer, was versuchst du mit diesem Schema zu erreichen? Es gibt wahrscheinlich einen besseren Weg, es zu tun.

    
BrenBarn 08.09.2012, 08:14
quelle
0

Wenn Sie __init__ anstelle von __new__ verwenden, können Sie die Attribute der Basisklasse erben:

%Vor%

Wenn A erstellt wird, wird Folgendes zurückgegeben:

%Vor%

Wenn B erstellt wird, wird Folgendes zurückgegeben:

%Vor%

Beachten Sie, und das hat @BrenBarn in seiner Antwort gesagt, dass foo nicht in% co_de ist % wenn attr erstellt wird. Deshalb löst der Code in der OP-Frage KeyError aus. Aufruf von B sucht jedoch nach self.foo in foo . Wenn es nicht gefunden werden kann, sucht es in seinen Basen nach IE B .

Die Metaklasse für beide Klassen kann durch Betrachten ihrer Klasse bestimmt werden:

%Vor%

Die Tatsache, dass die metaclass A -Methode aufgerufen wird, wenn __init__ zugewiesen und initialisiert wird, zeigt, dass B und self.foo in attr ebenfalls beweist, dass stdout 's Meta-Klasse B .     

Mark Mikofski 20.11.2013 19:09
quelle