Zapisz jako PDF

Transkrypt

Zapisz jako PDF
W Pythonie są trzy różne kategorie nazw zaczynających się od podkreślenia, ale tak naprawdę nie
mają one ze sobą dużo wspólnego. Najważniejsze są funkcje wywoływane automatycznie opisanej
[[../#Specjalne metody w Pythonie|gdzie indziej]], które mają po parze podkreśleń na początku i na
końcu. Oprócz tego występują zmienne prywatne, zaczynające się od jednego lub dwóch podkreśleń.
Takie zmienne nie są przeznaczone do tego, by się do nich odwoływać z spoza klasy czy modułu.
W szczególności przy wywołaniu from ... import *, czyli imporcie wszystkiego naraz, domyślnie
dostajemy tylko nazwy niezaczynające się od podkreślenia.
Rozróżnenie pomiędzy zmiennymi publicznymi i prywatnymi ma znaczenie w przypadku modułów
bibliotecznych — czyli takich które pełnią rolę służebną wobec innych modułów dostarczając im
metody do wywołania. Programy definiowane przez użytkownika też składają się z modułów, ale to
jak zostaną nazwane zmienne i funkcji oraz jakim będą ulegać zmianom wraz z rozwojem programu,
jest tak naprawdę istotne tylko dla autorów tego programu. Poniższe rozważania dotyczą więc
modułów przeznaczonych do wykorzystania przez innych, czyli w szczególności modułów w
standardowej bibliotece Pythona.
Nazwy niepoprzedzone podkreśleniem są elementem "interfejsu", czyli mogą być wykorzystywane
przez inne moduły i nie powinny ulegać zmianie wraz z rozwojem modułu w którym są
zadeklarowane. Rozpoczęcie nazwy od pojedynczego podkreślenia oznacza, że ta zmienna jest
elementem implementacji, który może ulec zmianie. Nie oznacza to, że do takiej zmiennej
uniemożliwiony jest dostęp, ani nawet że nie należy się do niej odwoływać. Pojedyncze podkreślenie
ostrzega tylko użytkownia przed tym, że dostęp do niej następuje na jego ryzyko.
Nazwy poprzedzone podwójnym podkreśleniem zachowują się w sposób szczególny. W trakcie
wykonywania definicji (czyli przy czytaniu programu), interpreter zamienia podwójne podkreślenie
na specjalny prefiks zależny od nazwy klasy czy modułu w którym następuje definicja. Np. jesli
zadeklarujemy pole __a w klasie A, to zostanie utworzone pole o nazwie _A__a, poprzez połączenie
nazwy klasy i pola. Celem tego podstawienia jest to, by klasa dziedzicząca mogła swobodnie
zdefiniować pole o takiej samej nazwie.
>>>
...
...
...
>>>
...
...
...
>>>
>>>
1
>>>
>>>
2
>>>
class A(object):
__v = 1
def a(self):
return self.__v
class B(A):
__v = 2
def b(self):
return self.__v
a = A()
print a.a()
b = B()
print b.b()
print b.a() # !
1
>>> b._B__v, b._A__v
(2, 1)
Widzimy, że mamy pole o pozornie takiej samej nazwie (__v), wykorzystywane przez A.a i B.b, bez
konfliktu. Oczywiście tak jak pokazuje ostatnia linijka, dostęp do pól "prywatnych" nie jest
szczególnie trudny, nawet spoza danej klasy.
Ponieważ wykorzystanie zmiennych prywatnych (z _ i __), nie jest w żaden sposób utrudnione, można
by się zapytać, jaki jest ich sens? Okazuje się, że te pierwsze (z pojedynczym podkreśleniem) mają
sens, bo mówią o intencjach, natomiast te drugie są raczej ukłonem w stronę programistów
przyzwyczajonych do innych języków programowania i wielekiego sensu w Pythonie nie mają.
Żartobliwe motto strzeszczające dostęp do zmiennych "prywantych" w Pythonie brzmi "we are all
consenting adults here". Ta fraza jest takim elementem Pythonowego folkloru, ale symbolizuje
zdecydowanie poważną filozofię. Skoro programista może użyć dostępnych funkcji w niewłaściwy
sposób i napisać niepoprawny program na tysiąc sposobów, skoro można nawet zmienić kod innych
klas w trakcie działania programu, to wymuszanie reguł dostępu do niektórych pól przez interpreter
byłoby tylko stratą czasu. Oczywiście zawsze należy chronić się przez pomyłkami, więc zmienne
"prywatne" są w czytelny sposób oznaczone podkreśleniem — i kiedy się ich używa z zewnątrz, to
jest to dozwolone, ale tylko na własną odpowiedzialność. Ogólna zasada jest taka, że zmienne
prywatne zdefiniowane w obiektach bibliotecznych mogą się zmienić z wersji na wersję, wedle
widzimisię autorów tych bibliotek. Natomiast w przypadku zmiennych publicznych, a zwłaszcza
udokumentowanych zmiennych publicznych, możemy oczekiwać, że nie ulegną one niekompatybilnej
zmianie w nowszych wersjach bez istotnego powodu. Zmienne podwójnie prywatne (z "__") są
natomiast używane znacznie rzadziej.