Python 3.3 - Hermetyzacja pól klasy + pyt. dot. kolejnych wersji Pythona

1

Witam
Właśnie przekopuje sobie informacje dot. OOP w pythonie, ogólnie wdaje sie w swiat pytona :) Piszę też w Javie skąd mam większość nawyków i nasunelo mi się pytanie, a może nawet pare, otóz:
1.Jak wyglada hermetyzacja pól w pythonie? wiem ze dodanie 2 underscorów przed nazwą pola to jakby nadac polu "private", ale z tego co widze nikt nie przykłada do tego wielkiej wagi, większość pól jest publiczna. Jak się z tym obchodzić?

2.Jeśli dobrze rozmiem, tworząc instancje klasy np User, w kodzie moge w dowolnym miejscu sobie stworzyć nowe pole w klasie, tak od po prostu je dodać. np:

class User:
    def __init__():
        self.name = ''
        self.lastname = ''
# SOME CODE
className = User()
# SOME CODE 2
className.dowolnaNazwaPola = 'dowolna wartosc pola'

# ...CODE CODE CODE...
i tutaj moge użyc zmiennej dowolnaNazwaPola tak jakbym ją tworzył bezposrednio w klasie, choć zrobiłem to całkiem poza nią, tak ze ona nawet o tym nie wie w czystej swojej postaci
 

To znaczy, że defacto pól nie deklaruje się bezpośrednio jak np w javie, tylko w konstruktorach? Z punktu widzenia tego co umiem z Javy mechanizm pól jest tutaj szalenie rozchwiany i mam przeczucie, że moze prowadzic do duzych problemów.

3.Czym różni się dostęp do zmiennej "zmiennaA" od "zmiennaB" od "zmiennaC":

class Example:
    zmiennaA = ''
    self.zmiennaB = ''  # <<< COFAM, nie moge tak zrobic, pytanie czemu :P?
    def __init__():
        self.zmiennaC = ''
  1. Istnieją w pythonie metody/pola statyczne tj np w javie, C# etc.?

I ostatnie pytanie tak btw. Zauważam pewną dziwną tendencje w swiecie pythona: otóż weźmy za łeb choćby PyQt wersje 4 i 5, albo nawet samego Pythona w wersji 2.7.6 i 3.3.5 ->> tutaj w kazdym API z wersji na wersje całkiem zmienia się struktura, inaczej nazywaja sie moduły, w innych miejscach nalezy szukac funkcji itd. Co mnie troszke dziwi, bo w javie tego nie doswiadczyłem :P
Często patrzyłem w API co robi funkcja, co zwraca itd: tutaj przy duck-typingu jest mała lipa, jakieś sugestie co do poznawania API w pythonie w jakiś sprawny sposób? :)

dzieki za cierpliwość, prosze o wyrozumiałość ;)

0

W tym API to chodzi o to, że równolegle są rozwijane dwie wersje pythona. Ponoć większość pisze w 2.x ale pewien nie jestem ;).

2
  1. Nie ma. Guido uznał że python to język dla dorosłych ludzi ;) Dodanie underscore powoduje częściowo ukrycie pól, bo ich nazwy zostają w runtime zmienione, ale ogólnie należy po prostu myśleć co sie robi. Zauważ że w javie jak bardzo chcesz to sobie refleksją i tak wyciągniesz prywatne pola, więc to jest tylko taki pic na wode, żeby zniechęcić ludzi do kombinowania. Python zakłada że wiesz co robisz ;]
  2. Tak jest. Aczkolwiek dobrą praktyką jest deklarowanie pól tylko w konstruktorze, żeby uniknąć dziwnych sytuacji. Ale technicznie rzecz biorąc możesz uzupełniać obiekty o nowe pola jeśli chcesz. Ale zauważ że próba odczytania wartości z pola które nie istnieje spowoduje wyjątek, więc nie jest aż tak tragicznie.
  3. Pierwsze pole jest polem statycznym. Drugiego nie możesz zadeklarować bo w tamtym miejscu nie ma "self" bo deklarujesz pola klasy (pola statyczne). Trzecie pole to zwykłe pole obiektu klasy (niestatyczne pole klasy).
  4. Pola omówiliśmy wyżej. Metody istnieją. Wystarczy że metoda nie ma parametru self jako pierwszego argumentu i dodasz do niej @staticmethod
  5. Python 2.X i 3.X to są dwa rozłączne języki bez kompatybilności. To nie jest tak że python 2.7 to wcześniejsza wersja pythona 3.3. Po prostu uznano że należy zaorać część pythona bo ssie i trzeba to zaprojektować od nowa. Ale że bylo sporo kodu działającego pod 2.X to ta linia też póki co jest utrzymywana.
0

świetnie @Shalom dzięki! ;]

Jako ze jeszcze pare pytan mi sie nasuwa to zadam :P
ad1. Czyli lepiej jest używać setterow/getterow w pythonie, czy odwolywac sie bezposrednio? bo skoro w tym jezyku brak jest typow zmiennych, to walidacja w np. setterze by sie przydała
2. Czy w pythonie istnieje cos takiego jak interfejs/klasy abstrakcyjne? nie jestem pewien, ale w javie zostal stworzony mechanizm interfejsów na rzecz pojedynczego dziedziczenia, python ma wielokrotne, więc chciałbym wiedziec czy to tutaj istnieje czy raczej nie
3. Teraz widuje często tematy "python 2.7 vs 3.3" ale sa one z przed roku i więcej, dlatego zastanawiam się czy na dzień dzisiejszy warto iść juz w 3.3? piszesz ze 2.7 "jest póki co utrzymywane" wiec wnioskuje ze predzej czy pozniej sie to skonczy, a widuje juz wersje nawet 3.4
4. Coś wartego polecenia do zapoznania w pythonie? jakis ciekawy framework, albo może bilbioteki przydatne w "codziennej pracy"? :P
5. Zastanawia mnie też gdzie mógłbym znaleźć jakiś ogólny zarys co zawiera bilbioteka standardowa pythona? i jedna, drobna rzecz: w Javie jak np. miałem konstruktor klasy X i było ich kilka, to pod ctrl+space czy tez w API na stronie oracla mialem podane co jest kolejnym argumentem i choćby po typie mogłem skojarzyc. Jako, że python tych typów nie ma, myśle skąd wiedzieć co podac w konstruktorze jakiejś-tam-klasy? kojarzyc po nazwach parametrów konstruktora? :D
6. Na ile znajmość C sie przydaje w Pythonie?
7. Zastanawia mnie na czym polegaja wyrażenia lambda? w javie 8 to wejdzie, w pythonie juz jest. Poczytałem, ze to tworzenie takich mini-funkcji np. interfejsów tj. Runnable itp, ale za mocno sie w to nie zaglebialem

1
  1. Lekcja na dziś: properties :) http://docs.python.org/3.4/library/functions.html#property
  2. Nie, a przynajmniej nie na poziomie języka. Ale ja osobiście wole jednak robić takie interfejsy zamiast polegać na duck-typingu. Po prostu robisz metody które mają w ciele
raise NotImplementedError("Implement this in subclass!")

i już :)
Ale możesz też polegać na duck-typingu, czyli po prostu zakładać ze obiekt ktory dostajesz implementuje metodę o danej nazwie. Jak się pomylisz to aplikacja wysypie się w runtime ;)
3. Moim zdaniem lepiej iść w 3, ale pisałem już wcześniej że w praktyce te różnice nie są aż takie wielkie i można z powodzeniem pisać kod który śmiga na obu.
4. Zależy co chcesz z tym pytonem robić. Warto wiedzieć co to PyPy i czemu jest lepsze niż inne interpretery. numpy niewątpliwie jest przydatną rzeczą. A oprócz tego pewnie warto zobaczyć jaki webowy framework -> Django, Flask. Osobiście nie polecam Web2py bo ssie.
5. W pythonie można, jeśli ktoś bardzo chce, deklarować typy parametrów a niektóre ide (np. PyCharm) na tej podstawie podpowiadają składnię. Jeśli chodzi o bibliotekę standardową pythona to link masz podany w 1.
6. Jeśli piszesz coś z uzyciem ctypes albo coś co działa na bardzo niskim poziomie to moze się przydać. Jeśli nie, to w ogóle się nie przyda.
7. Nie wiem co ma funkcja do interfejsu twoim zdaniem. Lambda to po prostu funkcja anonimowa. Zwykle stosuje sie to razem z jakimś map/filter/reduce. Jeśli nie wiesz co to, to doczytaj. Załóżmy że chcesz podwoić sobie liczby w tablicy. Możesz to zrobić za pomocą pętli, a możesz tak:

podwojone = map(lambda x: x*2, tablica)

Dzięki temu nie zaśmiecasz kodu taką zbędną funkcją.
Analogicznie silnia to moze być

silnia = reduce(lambda x,y: x*y, xrange(1,n))

Ale w pythonie lambdy są ograniczone do jednego wyrażenia. Tzn można lambdy użyć tylko jeśli ma być bardzo bardzo krótką funkcją.

0

ad1. Poćwiczyłem troche te properties i nie jestem pewien czy dobrze rozumiem jak działają te adnotacje, ale wiem jaki jest główny sens - tworze metody które będą wywołane, jak jakaś wartośc bedzie pobierana albo zmieniana? (gettowana/settowana). A ogólnie dla klasy User z polami name, lastname, age - to robic te property czy tylko wtedy kiedy potrzeba mi walidacji, a jesli nie to dostęp zostawić publiczny?

ad2. Możesz rzucic krótkim przykładem? bo zarys tego pomysłu mam ale nie bardzo wiem w którym miejscu w metodzie której klasy wrzucic ten raise NotImplementedError("text")

ad4. Jesli chodzi o te "podstawowe" bilbioteki to myśle o PyQt do GUI i Flask/Django jako web-dev. Tylko jak już bym chciał zaczynać kiedyś web-dev w pythonie to bym nie wiedział czy prostego(ponoć) Flaska czy troche bardziej złożonego ale znacznie szerzej uzywanego i rozbudowanego Django :P

ad7. no i to mi sie podoba, krótko i na temat. Doczytałem do czego są funkcje te które podałeś i już rozumiem ocb :) czasem widuje jakieś bardziej złożone działania z lambdami i póki co się to ciężko czyta, ale mam nadzieje, że niedługo wejdzie w krew. A tak btw to zauważyłem, że reduce() zostało usunięte w pythonie 3.3

Removed reduce(). Use functools.reduce() if you really need it; however, 99 percent of the time an explicit for loop is more readable.

z innych pytań:

  1. zastanawiam się po co jako pierwszy argument w każdej metodzie jest to "self"?
    dziwi mnie to troche, bo skoro python jest kierowany na droge czystości kodu, to po co paprać kod selfami skoro i tak potrzeba go wszędzie? :D np w Javie tego nie ma, a gdyby było to gdzie?
  2. raise działa jak throw w Javie?

EDIT
@Shalom A co do tych interfejsów, może troche źle się wyraziłem :P chodziło mi o to, że jak mamy metode:

 public void doSth(Runnable runnable){
 //CODE
}

To chcąc gdzieś tam jej użyc, z racji że musimy zaimplementowac metode run(); robimy np:

jakisObiekt.doSth(new Runnable(){
  public void run(){
      //CODE
}
}

I z tego co rozumiem w javie - bo jeszcze się w to nie zagłębiałem, możemy użyć lambdy za pomocą operatora "->", ale jeszcze nie wiem jak :D jeśli nie to nie bij za mocno ;]
ps. java 8 to juz weszła czy jeszcze nie?:D bo niby download na oracle.com jest

1 użytkowników online, w tym zalogowanych: 0, gości: 1