Wszystko omówię na podstawie przykładowej klasy Pythona.
class MojaKlasa(object):
zmienna_statyczna = 12
def __init__(self):
self.zwykla_zmienna = 'a'
print 'Ja się wywołam przy toworzeniu'
def __del__(self):
print 'Ja się wywołam przy usuwaniu'
Powyższa klasa dziedziczy po object. Dalej w ciele klasy definiujemy zmienną o nazwie zmienna_statyczna i przypisujemy jej wartość 12. W języku Python wszystkie zmienne definiowane w ciele klasy zachowują się jak zmienne statyczne. Metoda __init__ (nazwa zaczyna się i kończy od dwóch podkreślników) wywoła się zaraz po utworzenia obiektu :) Zaś metoda __del__ podczas jego usuwania. Piszę celowo "wykona się zaraz po utworzeniu", a nie "jest konstruktorem" ponieważ jest to stwierdzenie bliższe prawdzie.
Metody statyczne oznaczamy podając przed ich deklaracją @staticmethod:
Metoda jak widać nie przyjmuje parametru self (nie miałoby to sensu skoro jest statyczna i może być wywołana dla klasy bez tworzenia jej instancji). Aby odwołać się w niej do zmiennej statycznej możemy użyć Klasa.zmienna gdzie klasa to nazwa klasy a zmienna to nazwa zmiennej zadeklarowanej w jej ciele. Podobnie wygląda wywołanie metody statycznej Klasa.mojaStatycznaMetoda().
class Klasa(object):
zmienna = 12
@staticmethod
def mojaStatycznaMetoda():
return Klasa.zmienna
Wszystkie metody przyjmują jako pierwszy parametr self, czyli "samego siebie". Jest to jawny zapis tego co w C++ jest ukryte w mechanizmach języka i traktowane "domyślnie" (wszak możesz w metodach klasy C++ odwoływać się do obiektu z użyciem słówka this chociaż nigdzie go nie przekazujesz). Wszystkie atrybuty zdefiniowane w metodzie __init__ z użuyciem self.nazwa_zmiennej są jak widać zmienny obiektu nie klasy co po przeanalizowaniu znaczenia zmiennej self (ja, moja instancja, aktualnie tworzony obiekt) ma rzeczywiście sens :) Zmienne należą do obiektu (self), są definiowane dla niego (konkretnej instancji) nie zaś w ciele samej klasy.
A co z atrybutami: prywatny, publiczny. Domyślnie wszystkie metody i atrybuty w Pythonie są publiczne. I tutaj, aby zdefiniować elementy prywatne, zrezygnowano ze słów kluczowych na rzecz konwencji. Aby element klasy był prywatny jego nazwa musi zaczynać się od dwóch podkreślników to jest od __. Tak więc atrybuty:
Wszystko czego nazwa zaczyna się od dwóch podkreślników będzie prywatne, ze swojej natury.
class KolejnkaKlasa(object):
__zmienna_statyczna
def __init__(self):
self.__top_secret
def __nie_wywolasz_mnie(self):
pass
pass
Co można powiedzieć o wartościach protected ? Są - ale istnieją jedynie z umowy. Umownie - wszystko czego nazwa rozpoczyna się od jednego znaku podkreślenia _ jest parametrem chronionym. Umowanie - ponieważ faktycznie ma się do niego nadal publiczny dostęp. Czy to znaczy, że Python nie wspiera metod i atrybutów chronionych w klasach. Tak - w Pythonie nie zaimplementowano tego mechanizmu. Zrobiono to celowo. Zainteresowanych odsyłam do wątku "Protected Methods and Python" na grupie dyskusyjnej języka. Jak widać po dyskusji, ufając intuicji autorytetu jakim jest Bjarne StrouStrup (twórca języka C++) atrybty i metody chronione to zły, zbędny mechanizm :) Więc nie martw się nic nie tracisz :)
No comments:
Post a Comment