Beachten Sie, dass Python die Art und Weise geändert hat, wie Sie Unterklassen erstellen. Es gibt also zwei Möglichkeiten, dies zu tun, und sie werden nicht gemischt. Beim Mischen wird eine Fehlermeldung angezeigt. Lesen Sie diesen Beitrag, um den Unterschied zu sehen: stackoverflow.com/questions/1713038/…
Mark Lakata
Antworten:
88
# Initialize using Parent#classMySubClass(MySuperClass):def __init__(self):MySuperClass.__init__(self)
Oder, noch besser, die Verwendung der in Python integrierten Funktion super()(siehe Python 2 / Python 3- Dokumentation) ist möglicherweise eine etwas bessere Methode, um das übergeordnete Element zur Initialisierung aufzurufen:
# Better initialize using Parent (less redundant).#classMySubClassBetter(MySuperClass):def __init__(self):
super(MySubClassBetter, self).__init__()
Oder genau das Gleiche wie oben, außer dass die Nullargumentform von verwendet wird super(), die nur innerhalb einer Klassendefinition funktioniert:
OTOH, einige Leute warnen davor super, insbesondere für neue Python-Programmierer (z. B. Lutz). Ich vermeide es.
Eric
6
Der einzige Grund , zu vermeiden super, wenn Sie die Unterschiede zwischen dem, wie nicht verstehen , superfunktioniert in Python, und wie super/ parentarbeitet in anderen Sprachen. Zugegeben, dies ist für Leute aus anderen Sprachen nicht offensichtlich, aber ich würde nicht schlussfolgern, dass dies es als etwas qualifiziert, vor dem man "warnen" sollte. Es funktioniert . Es funktioniert einfach anders. Lesen Sie einfach, was es in Python tatsächlich tut, bevor Sie sich über Ergebnisse beschweren, die Sie nicht erwartet haben.
classSuperHero(object):#superclass, inherits from default objectdef getName(self):raiseNotImplementedError#you want to override this on the child classesclassSuperMan(SuperHero):#subclass, inherits from SuperHerodef getName(self):return"Clark Kent"classSuperManII(SuperHero):#another subclassdef getName(self):return"Clark Kent, Jr."if __name__ =="__main__":
sm =SuperMan()print sm.getName()
sm2 =SuperManII()print sm2.getName()
Sie müssen diese __init__Methode nur definieren, wenn Sie weiteren Code hinzufügen möchten, andernfalls wird die ursprüngliche Init-Methode trotzdem verwendet (obwohl es erwähnenswert ist und ein vollkommen gültiger Code ist)
dbr
2
Ich denke, die Frage war vage genug, um anzunehmen, dass möglicherweise weiterer Code hinzugefügt wird. Es ist besser, zu viele Informationen als nicht genug bereitzustellen und eine andere Frage zu stellen, wenn das OP sie implementiert. :)
Cool. Dies ist, wonach ich eigentlich gesucht habe, dh eine Unterklasse ohne Erweiterung / Überschreibungen des Super.
BuvinJ
9
In den obigen Antworten wird das superohne (Schlüsselwort-) Argumente initialisiert. Oft möchten Sie dies jedoch tun und einige eigene „benutzerdefinierte“ Argumente weitergeben. Hier ist ein Beispiel, das diesen Anwendungsfall veranschaulicht:
classSortedList(list):def __init__(self,*args, reverse=False,**kwargs):
super().__init__(*args,**kwargs)# Initialize the super class
self.reverse = reverse
self.sort(reverse=self.reverse)# Do additional things with the custom keyword arguments
Dies ist eine Unterklasse list, die sich beim Initialisieren sofort in die durch das reverseSchlüsselwortargument angegebene Richtung sortiert , wie die folgenden Tests veranschaulichen:
import pytest
def test_1():assertSortedList([5,2,3])==[2,3,5]def test_2():SortedList([5,2,3], reverse=True)==[5,3,2]def test_3():with pytest.raises(TypeError):
sorted_list =SortedList([5,2,3],True)# This doesn't work because 'reverse' must be passed as a keyword argumentif __name__ =="__main__":
pytest.main([__file__])
Dank der Weitergabe von *argsan superkann die Liste initialisiert und mit Elementen gefüllt werden, anstatt nur leer zu sein. (Beachten Sie, dass dies reverseein reines Schlüsselwortargument gemäß PEP 3102 ist. )
Es gibt eine andere Möglichkeit, Unterklassen in Python mit einer Funktion dynamisch zu erstellen type():
SubClass= type('SubClass',(BaseClass,),{'set_x': set_x})# Methods can be set, including __init__()
Normalerweise möchten Sie diese Methode verwenden, wenn Sie mit Metaklassen arbeiten. Wenn Sie einige Automatisierungen auf niedrigerer Ebene ausführen möchten, ändert dies die Art und Weise, wie Python Klassen erstellt. Höchstwahrscheinlich müssen Sie dies niemals auf diese Weise tun, aber wenn Sie dies tun, wissen Sie bereits, was Sie tun.
Diese Antwort wäre hilfreicher, wenn Sie eine Erklärung
hinzufügen
4
Obwohl dieser Code zur Lösung des Problems beitragen kann, erklärt er nicht, warum und / oder wie er die Frage beantwortet. Die Bereitstellung dieses zusätzlichen Kontextes würde den langfristigen Bildungswert erheblich verbessern. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, einschließlich der Einschränkungen und Annahmen.
Toby Speight
2
Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich dabei, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Antworten:
Oder, noch besser, die Verwendung der in Python integrierten Funktion
super()
(siehe Python 2 / Python 3- Dokumentation) ist möglicherweise eine etwas bessere Methode, um das übergeordnete Element zur Initialisierung aufzurufen:Oder genau das Gleiche wie oben, außer dass die Nullargumentform von verwendet wird
super()
, die nur innerhalb einer Klassendefinition funktioniert:quelle
super
, insbesondere für neue Python-Programmierer (z. B. Lutz). Ich vermeide es.super
, wenn Sie die Unterschiede zwischen dem, wie nicht verstehen ,super
funktioniert in Python, und wiesuper
/parent
arbeitet in anderen Sprachen. Zugegeben, dies ist für Leute aus anderen Sprachen nicht offensichtlich, aber ich würde nicht schlussfolgern, dass dies es als etwas qualifiziert, vor dem man "warnen" sollte. Es funktioniert . Es funktioniert einfach anders. Lesen Sie einfach, was es in Python tatsächlich tut, bevor Sie sich über Ergebnisse beschweren, die Sie nicht erwartet haben.Ein heldenhaftes kleines Beispiel:
quelle
Der Abschnitt zur Vererbung in der Python-Dokumentation erläutert dies ausführlicher
quelle
__init__
Methode nur definieren, wenn Sie weiteren Code hinzufügen möchten, andernfalls wird die ursprüngliche Init-Methode trotzdem verwendet (obwohl es erwähnenswert ist und ein vollkommen gültiger Code ist)Klasse2 ist eine Unterklasse von Klasse1
quelle
In den obigen Antworten wird das
super
ohne (Schlüsselwort-) Argumente initialisiert. Oft möchten Sie dies jedoch tun und einige eigene „benutzerdefinierte“ Argumente weitergeben. Hier ist ein Beispiel, das diesen Anwendungsfall veranschaulicht:Dies ist eine Unterklasse
list
, die sich beim Initialisieren sofort in die durch dasreverse
Schlüsselwortargument angegebene Richtung sortiert , wie die folgenden Tests veranschaulichen:Dank der Weitergabe von
*args
ansuper
kann die Liste initialisiert und mit Elementen gefüllt werden, anstatt nur leer zu sein. (Beachten Sie, dass diesreverse
ein reines Schlüsselwortargument gemäß PEP 3102 ist. )quelle
Es gibt eine andere Möglichkeit, Unterklassen in Python mit einer Funktion dynamisch zu erstellen
type()
:Normalerweise möchten Sie diese Methode verwenden, wenn Sie mit Metaklassen arbeiten. Wenn Sie einige Automatisierungen auf niedrigerer Ebene ausführen möchten, ändert dies die Art und Weise, wie Python Klassen erstellt. Höchstwahrscheinlich müssen Sie dies niemals auf diese Weise tun, aber wenn Sie dies tun, wissen Sie bereits, was Sie tun.
quelle
quelle
Sie nutzen:
Weitere Informationen finden Sie in den Python-Dokumenten, Abschnitt 9.5 .
quelle
quelle
quelle
Die Unterklasse in Python erfolgt wie folgt:
Hier ist ein Tutorial über Python, das auch Klassen und Unterklassen enthält.
quelle