🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.python
Article #26984

Re: dyskryptory

#26984
From: Daniel Mróz
Date: Fri, 27 Nov 2009 23:47
58 lines
3882 bytes
On 27.11.2009, Daniel Mróz <beorn@alpha.pl> wrote:
> Nikt Ci nie każe używać __get__/__set__, możesz przypisywać/pobierać
> wartości bez nich. Jeśli chcesz jednak np. dodać sprawdzanie typu (z rzucaniem
> stosownego wyjątku), te metody pozwalają Ci na zrobienie tego niejawnie.
> W ten sposób klasa sama się zatroszczy o siebie, a Ty nie będziesz musiał
> używać javowych potworków typu:
>
> 	obj.setA(value)
>
> Oczywiście można je wykorzystać także do innych zabaw. Co Ci tylko
> przyjdzie na myśl. Masz mechanizm, który *możesz* wykorzystać, ale
> *nie musisz*.
OK, po czyms takim nawet ja nie byłbym przekonany co do potęgi tego
mechanizmu, więc wytłumaczę jeszcze raz na przykładzie (z życia
wziętym).
Wyobraź sobie, że piszesz aplikację operująca na bezklasowych
zakresach adresów IP. Naturalnym jest, że w tym celu tworzy się klasę
(pythonową) zawierającą m.in. atrybuty początku i końca zakresu.
Taką klasę w wersji podstawowej każdy jest w stanie zbudowac sobie
w myślach bez większego wysiłku. Są jednak cztery problemy:
1. Klasa wewnętrznie przechowuje początek i koniec zakresu w
postaci liczbowej (aby wykonywać operacje typu "liczba adresów IP
w zakresie", czy "powiększ zakres o kolejnych 400 adresów"), zaś
człowiek (programista) bardziej skłonny jest używać postaci znakowej
("xxx.xxx.xxx.xxx"). Transformacji może dokonać automagicznie
konstruktor klasy.
2. Chcąc zmienić wartość początku i/lub końca zakresu w obiekcie
trzeba pamiętać o zamianie adresu IP na liczbę. Metoda zamiany jest
dość złożona i trudna do zapamiętania, gdyż wymaga użycia metod
modułów socket oraz struct. Trzeba zatem bawić się w metody statyczne
lub dodatkowe funkcje.
3. Przy zmianie dowolnego z tych dwóch atrybutów trzeba pamiętać,
że zakres nie może być odwrócony, tzn. początek nie może być za końcem.
Pilnowanie tego może byc strasznie upierdliwe.
4. Często potrzebujemy odczytać wartości początku i końca zakresu
w postaci znakowej, np. aby zaprezentować wynik użytkownikowi.
Wymaga to albo przechowywania w obiekcie zarówno liczb jak i ich
odpowiedników znakowych (i aktualizować przy każdej zmianie wartości),
albo definiowania dodatkowych metod, które zwrócą string po
transformacji, albo tworzyć dodatkowe funkcje.

Wszystkie te cztery problemy załatwiają metody __get__() i __set__().
Przy nadawaniu i odczycie wartości mogą dokonywać automatycznej
transformacji z/na wartość liczbową (jeśli potrzeba), pilnować żeby
zakres nie był odwrócony i dostarczać "wirtualnych" atrybutów znakowych,
których wartość będzie generowana w locie.

Dwie małe metody, masa problemów z głowy.


Pozdrawiam
Beorn

-- 
Daniel 'Beorn' Mróz <beorn@alpha.pl>    http://127.0.0.1/beorn
[GIT d s:- a-@ C++++ UL++++$ P+ L++++ E--- W+ N+++ o? K- w---]
[O- M- V!  PS+ PE++ Y+ PGP++ t- 5  X R !tv b+ DI D++ G++ e h*]
[                          r++  y+                           ]
Technical Details
Message-ID: <slrnhh0pgf.llt.beorn@pino.cyberdeck.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.rmf.pl!agh.edu.pl!news.agh.edu.pl!news.onet.pl!news.nask.pl!news.nask.org.pl!newsfeed.atman.pl!not-for-mail
References: <slrnhh0li5.ljo.beorn@pino.cyberdeck.pl>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.rmf.pl!agh.edu.pl!news.agh.edu.pl!news.onet.pl!news.nask.pl!news.nask.org.pl!newsfeed.atman.pl!not-for-mail
From: Daniel Mróz <beorn@alpha.pl>
Newsgroups: pl.comp.lang.python
Subject: Re: dyskryptory
Date: Fri, 27 Nov 2009 23:47:33 +0000 (UTC)
Organization: A tak se walimy młotkami d:-/
Lines: 58
Message-ID: <slrnhh0pgf.llt.beorn@pino.cyberdeck.pl>
References: <slrnhh0li5.ljo.beorn@pino.cyberdeck.pl>
NNTP-Posting-Host: fw2.itvp.pl
Mime-Version: 1.0
X-Trace: node2.news.atman.pl 1259365653 14404 217.17.39.4 (27 Nov 2009 23:47:33 GMT)
X-Complaints-To: usenet@atman.pl
NNTP-Posting-Date: Fri, 27 Nov 2009 23:47:33 +0000 (UTC)
User-Agent: slrn/0.9.8.1pl2.1 (Linux)
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit