Wydawało mi się, że znam całkiem dobrze pythona, tymczasem czytam manual kivy i aż się zdziwiłem, kiedy składnia prezentowana jako prosty przykład okazała się dla mnie nie zrozumiała.
Aż mi głupio zadawać tak proste pytanie, ale może ktoś się zlituje i oszczędzi mi kopania ( manual pythona mi tego jakoś nie wyjaśnia ), bo w googlu ciężko będzie znaleźć.
Mianowicie:
definiowanie klasy wiadome. Dziedziczy ona po klasie "object". Metoda init jest metodą wywoływaną bezpośrednio po inicjalizacji obiektu ( z tego co pamiętam, bo chyba właśnie tym się różnił init od konstruktora, że nie wywołuje klasy, tylko konkretyzuje ją, ale dawno w to nie wnikałem ).Kod:class MyClass(object): def __init__(self): super(MyClass, self).__init__() self.numeric_var = 1
Kolejna linijka jednak jest dla mnie zrozumiała niczym pijany szwab. Rozumiejąc dokładnie tak jak tłumaczy podstawowy samouk pythona z oficjalnej strony. Wywołujemy funkcje __init__() klasy super z argumentami wywołania tejże klasy MyClass i self. Niech będzie, że MyClass to właśnie inicjowana klasa. A raczej definiowana. A self po co?
No właśnie! Definiowana a nie inicjowana. Heh chyba już wiem. Pisanie dobrze się jeszcze chwilę się zastanowić przed wysłaniem posta .
Podejrzewam, że self wskazuje, że MyClass ma być bieżącą instancją właśnie inicjowanego ( tzn. konkretyzowanego o ile dobrze pamiętam różnicę pomiędzy __init__ a konstruktorem ) obiektu.
Jeżeli dobrze rozumuje, to kiedy tego typu kod wykonam bez self, linijka super( MyClass ).__init__() Utworzy nowy obiekt jako argument klasy.
Da się to sprawdzić doświadczalnie pisząc prosty kod. Zaraz się tym pobawię a tym czasem może ktoś mnie wyprowadzi z błędu, w którym mi się wydaje, że jednak jestem. Bo z tego co mi wiadomo, to co opisałem powinno się robić tak:
Grrr po ponad dwóch latach obcowania z pythonem mieć problem ze zrozumieniem składni ;/ Jestem wściekły na samego siebie.Kod:super.__init__( self, MyClass )
_____________Dopisek po przemyśleniach_____________
Zanim zabrałem się za eksperymenty jeszcze podukałem nad dobrze znanym mi działaniem zmiennej self. Skoro przyjmuje ona wartość bieżącej instancji. To załóżmy, że tworzymy obiekt "klasa" klasy. MyClass. W tym wypadku self przyjmuje wartość "klasa". Wobec czego można by instancje przedstawić w ten sposób:
Jeśli rozumieć tak ( a raczej tak, bo argument to tylko argument więc skąd mi przyszło do głowy, że drugi argument decyduje o tym czy pierwszy będzie nową instancją o_O ), to po prostu super jest wywoływana z dwoma argumentami. Z tym, że MyClass nie jest obiektem, tylko jego definicją. Muszę więc sprawdzić, to co miałem sprawdzić już wcześniej. Czy kiedy dam jako argument nazwę klasy, interpreter wywali błąd, czy wywoła funkcje __init__ i poda zainicjowany obiekt jako wartość argumentu. Moim zdaniem tak, bo identycznie robi przy podaniu funkcji jako argument ( najpierw wykonuje a jako argument podaje wartość którą zwraca ). Tylko dlaczego te argumenty nie są podane do funkcji, tylko do klasy? Funkcje da się wywołać bez argumentów tylko jeżeli funkcja nie ma zdefiniowanych parametrów, albo parametry są opcjonalne. Fajnie, tylko, że argumenty wywołania klasy są przekazywane jako parametry funkcji init.... No tak wychodziłoby na to, że zapis z argumentami za nazwą klasy jest równoważny z argumentami do init ( wszak i tak argumenty idą do init ).Kod:# Instancja klasa klasy MyClass def __init__(klasa): super(MyClass, klasa).__init__() self.numeric_var = 1
Jestem na 80% pewny, że to będzie tak. Pozostaje sprawdzić doświadczalnie.