Vererbt von einer Instanz in Python

8

In Python möchte ich eine Instanz der Child-Klasse direkt aus einer Instanz der Parent-Klasse konstruieren. Zum Beispiel:

%Vor%

Dies ist ein Hack, von dem ich dachte, dass er funktionieren könnte:

%Vor%

Aber wenn ich renne

%Vor%

Ich bekomme:

%Vor%

Es scheint, dass der Hack genau so funktioniert, wie ich es erwartet habe, aber der Compiler wirft am Ende einen TypeError. Ich habe mich gefragt, ob ich TypeError überladen könnte, um das B = Child (A) -Idiom zu ignorieren, aber ich war mir nicht sicher, wie ich das machen sollte. Bitte geben Sie mir in jedem Fall Ihre Lösungen zum Erben von Instanzen?

Danke!

    
cdleary 04.07.2009, 01:02
quelle

6 Antworten

7

Sobald __new__ in der Klasse Child eine Instanz von Child zurückgibt, wird Child.__init__ (mit den gleichen Argumenten __new__ ) für diese Instanz aufgerufen - und anscheinend erbt es nur Parent.__init__ , die nicht gut mit nur einem Argument aufgerufen werden kann (das andere Parent , A ).

Wenn es keinen anderen Weg gibt, ein Child zu machen, können Sie ein Child.__init__ definieren, das entweder ein arg akzeptiert (was es ignoriert) oder drei (in diesem Fall ruft es Parent.__init__ auf). Aber es ist einfacher, auf __new__ zu verzichten und die gesamte Logik in Child.__init__ zu haben, indem einfach die Parent.__init__ entsprechend aufgerufen wird!

Um dies mit einem Codebeispiel zu konkretisieren:

%Vor%     
Alex Martelli 04.07.2009 01:11
quelle
5

OK, also habe ich nicht bemerkt, dass Sie mit einer statischen Kopie der Argumente zufrieden waren, bis ich mit meiner Lösung schon halb fertig war. Aber ich habe beschlossen, es nicht zu verschwenden, also hier ist es sowieso. Der Unterschied zu den anderen Lösungen besteht darin, dass die Attribute tatsächlich vom übergeordneten Objekt abgerufen werden, auch wenn sie aktualisiert wurden.

%Vor%

Wenn wir das jetzt tun:

%Vor%

Eine allgemeinere Version davon finden Sie im Paket Ссылка . Es ist in der Tat in einigen Fällen eine blutige Notwendigkeit Lösung.

    
Lennart Regebro 04.07.2009 10:12
quelle
3

Sie definieren keinen Konstruktor (init) für Child, daher wird der Parent-Konstruktor aufgerufen, wobei 4 Argumente erwartet werden, während nur 2 übergeben werden (von new). Hier ist ein Weg, um zu erreichen, was Sie wollen:

%Vor%     
ars 04.07.2009 01:18
quelle
2

Ich weiß, dass dies ein extrem alter Thread ist, aber ich stieß vor kurzem auf dieselbe Herausforderung wie Alexandra, und dies war das relevanteste Thema, das ich finden konnte. Ich hatte eine Elternklasse mit vielen, vielen Attributen, und ich wollte im Wesentlichen eine Instanz davon "patchen", indem ich alle seine Methoden und Attribute behielt, einige hinzufügte und andere änderte / überschrieb. Eine einfache Unterklasse würde nicht funktionieren, weil die Attribute vom Benutzer zur Laufzeit ausgefüllt würden und ich nicht einfach die Standardwerte von der Elternklasse erben könnte. Nach viel Basteln fand ich einen sehr sauberen (wenn auch ziemlich hacky) Weg, dies mit __new__ zu tun. Hier ist ein Beispiel:

%Vor%

Der einzige spezielle Teil ist das Ändern des __class__ -Attributs der Parent-Klasse im Child-Konstruktor. Aus diesem Grund wird die Methode __init__ des Childs wie üblich aufgerufen, und meines Wissens sollte die Child-Klasse genauso funktionieren wie jede andere vererbte Klasse.

    
DaveTheScientist 15.08.2012 18:09
quelle
2

Ich finde dies (Kapselung) am saubersten:

%Vor%

Auf diese Weise können Sie die gesamte Methode von Parent und Ihre eigene verwenden, ohne dass Sie auf die Probleme der Vererbung stoßen.

    
elyase 06.01.2013 13:22
quelle
0

Danke, Jungs, das war schnell! Ich las zuerst Alex 'Kommentar und ich schrieb die% code% des Kindes als

um %Vor%

was sehr ähnlich zu dem ist, was abhinavg vorgeschlagen hat (wie ich gerade herausgefunden habe). Und es funktioniert. Nur seine und ars 'Linie

%Vor%

ist sauberer als meins.

Nochmals vielen Dank !!

    
Alexandra 04.07.2009 01:37
quelle