Java i C ++ wymagają wywołania konstruktora klasy bazowej ze względu na układ pamięci.
Jeśli masz klasę BaseClassz członkiem field1i tworzysz nową klasę, SubClassktóra dodaje członka field2, to wystąpienie SubClasszawiera miejsce na field1i field2. Potrzebujesz konstruktora BaseClassdo wypełnienia field1, chyba że chcesz, aby wszystkie klasy dziedziczące powtarzały BaseClassinicjalizację we własnych konstruktorach. A jeśli field1jest prywatny, dziedziczenie klas nie może zostać zainicjowane field1.
Python to nie Java ani C ++. Wszystkie wystąpienia wszystkich klas zdefiniowanych przez użytkownika mają ten sam „kształt”. Są to po prostu słowniki, w których można wstawiać atrybuty. Przed wykonaniem jakiejkolwiek inicjalizacji wszystkie wystąpienia wszystkich klas zdefiniowanych przez użytkownika są prawie dokładnie takie same ; to tylko miejsca do przechowywania atrybutów, które jeszcze nie przechowują.
Dlatego też dla podklasy Pythona ma sens, aby nie wywoływać konstruktora klasy bazowej. Mógłby po prostu dodać atrybuty, gdyby chciał. Nie ma miejsca zarezerwowanego dla danej liczby pól dla każdej klasy w hierarchii i nie ma różnicy między atrybutem dodanym przez kod z BaseClassmetody a atrybutem dodanym przez kod z SubClassmetody.
Jeśli, co jest powszechne, SubClassfaktycznie chce mieć wszystkie BaseClassniezmienniki ustawione przed przystąpieniem do własnych dostosowań, to tak, możesz po prostu zadzwonić BaseClass.__init__()(lub użyć super, ale jest to skomplikowane i czasami ma swoje własne problemy). Ale nie musisz. Możesz to zrobić przed, po lub z różnymi argumentami. Do diabła, gdybyś chciał, mógłbyś wywołać the BaseClass.__init__z innej metody całkowicie niż __init__; może masz jakieś dziwne, leniwe inicjowanie.
Python osiąga tę elastyczność dzięki prostocie. Obiekty inicjalizujesz, pisząc __init__metodę, która ustawia atrybuty self. Otóż to. Zachowuje się dokładnie jak metoda, ponieważ jest dokładnie metodą. Nie ma innych dziwnych i nieintuicyjnych zasad dotyczących rzeczy, które trzeba zrobić najpierw lub rzeczy, które wydarzy się automatycznie, jeśli nie zrobisz innych rzeczy. Jedynym celem, jaki musi spełniać, jest być punktem zaczepienia do wykonania podczas inicjalizacji obiektu w celu ustawienia początkowych wartości atrybutów, i właśnie to robi. Jeśli chcesz, aby robił coś innego, napisz to wyraźnie w swoim kodzie.
__init__metodę, a nawet może automatycznie wyszukać podklasy i je ozdobić.