Java und C ++ erfordern, dass ein Basisklassenkonstruktor aufgrund des Speicherlayouts aufgerufen wird.
Wenn Sie eine Klasse BaseClassmit einem Mitglied field1haben und eine neue Klasse erstellen SubClass, die ein Mitglied hinzufügt field2, SubClassenthält eine Instanz von Platz für field1und field2. BaseClassZum Ausfüllen benötigen Sie einen Konstruktor von field1, es sei denn, Sie benötigen alle ererbenden Klassen, um BaseClassdie Initialisierung in ihren eigenen Konstruktoren zu wiederholen . Und wenn field1es privat ist, kann das Erben von Klassen nicht initialisiert werden field1.
Python ist nicht Java oder C ++. Alle Instanzen aller benutzerdefinierten Klassen haben dieselbe 'Form'. Sie sind im Grunde nur Wörterbücher, in die Attribute eingefügt werden können. Bevor eine Initialisierung durchgeführt wurde, sind alle Instanzen aller benutzerdefinierten Klassen fast genau gleich . Sie sind nur Orte zum Speichern von Attributen, die noch keine gespeichert haben.
Daher ist es für eine Python-Unterklasse durchaus sinnvoll, ihren Basisklassenkonstruktor nicht aufzurufen. Es könnte einfach die Attribute selbst hinzufügen, wenn es wollte. Es ist kein Platz für eine bestimmte Anzahl von Feldern für jede Klasse in der Hierarchie reserviert, und es gibt keinen Unterschied zwischen einem Attribut, das durch Code aus einer BaseClassMethode hinzugefügt wurde, und einem Attribut, das durch Code aus einer SubClassMethode hinzugefügt wurde .
Wenn, wie üblich, SubClasstatsächlich alle BaseClassInvarianten eingerichtet werden sollen, bevor die eigene Anpassung vorgenommen wird, können Sie diese einfach aufrufen BaseClass.__init__()(oder verwenden super, aber das ist kompliziert und hat manchmal eigene Probleme). Aber das musst du nicht. Und Sie können es vorher oder nachher oder mit verschiedenen Argumenten tun. Zur Hölle, wenn Sie wollten, könnten Sie das BaseClass.__init__von einer anderen Methode ganz aufrufen als __init__; Vielleicht haben Sie eine bizarre Sache mit der faulen Initialisierung.
Python erreicht diese Flexibilität, indem es die Dinge einfach hält. Sie initialisieren Objekte, indem Sie eine __init__Methode schreiben , die Attribute festlegt self. Das ist es. Es verhält sich genau wie eine Methode, weil es genau eine Methode ist. Es gibt keine anderen seltsamen und nicht intuitiven Regeln für Dinge, die zuerst erledigt werden müssen, oder für Dinge, die automatisch passieren, wenn Sie keine anderen Dinge tun. Der einzige Zweck, dem es dienen muss, ist ein Hook, der während der Objektinitialisierung ausgeführt wird, um anfängliche Attributwerte festzulegen, und genau das tut es. Wenn Sie möchten, dass es etwas anderes tut, schreiben Sie dies explizit in Ihren Code.
__init__Methode zu erben , und vielleicht sogar automatisch nach Unterklassen suchen und diese dekorieren.