[python] Trida pro IP adresu, vyjimky (bylo RE: Re: nevznik objektu)

Přikryl Petr prikryl na atlas.cz
Středa Březen 24 13:41:50 CET 2010


Zdravím,

Přidám svůj pohled na řešení problému s IP objektem 
a na pohled na výjimky (s ohledem na vaše vzdělání
a působení).

S tím návrhem třídy IP bych se přimlouval k promyšlení
pohledu na to, co objekt třídy IP reprezentuje. Zohlednil
bych taky to, jak by to vypadalo v jiných jazycích, třeba
v C++. Prakticky žádný jazyk neumožní korektní "nevznik"
objektu -- pokud nedojde k nějaké nízkoúrovňové havárii.

Objekt v kompilovaných jazycích buď vytvořím staticky, 
na zásobníku (jakoby staticky, ale v prostoru zásobníku)
nebo dynamicky (new nebo něco takového). Jakmile vznikne,
zpřístupňuji jej přímo přes jméno proměnné (statický
objekt nebo na zásobníku -- tohle v Pythonu není),
přes referenci (to je případ Pythonu) nebo přes ukazatel.

Pouze v případě použití ukazatele mám možnost vrátit
alternativně hodnotu NULL. Pak to musí být případ,
který popisoval Petr Messner -- zavolat funkci a ta
vrátí buď NULL nebo hodnotu ukazatele na vytvořený 
objekt. Tohle by v Pythonu bylo stejné.

Při návrhu se musí rozhodnout, co vlastně objekt
třídy IP má vyjadřovat. Má vyjadřovat zachycení 
přání vnějšího prostředí (uživatele, volajícího kódu)
získat objekt s právě takovou IP adresou? Má existence
objektu vyjadřovat platnost IP adresy? Co to vůbec
je "platná IP adresa"? Je to syntakticky správně 
napsaná adresa, nebo je to adresa, která se dá skutečně
použít? Nebo dokonce adresa, která mi umožní udělat
operaci, kterou bych chtěl provést (tj. s ověřením,
že se přes ni někam dostanu)? A co když se syntaxe
IP adres v budoucnu změní? Jak to udělat, abych
toho musel předělávat co nejméně?

V tomto smyslu se přimlouvám za to, aby objetk třídy
IP vznikl vždy, ale aby se bránil použití v případě,
kdy má nepoužitelný obsah -- v okamžiku použití, 
nikoliv v okamžiku vzniku (viz například momentální
nedostupnost přes IP). Na vyšší úrovni si pak můžu
rozhodnout, zda objekt s nepoužitelnou IP adresou
(po otestovnání jeho vlastností) ponechám nebo zruším.

V tomto smyslu se přimlouvám znovu za návrh Petra 
Messnera -- využít __nozero__. Protože přesně pro
tento účel byla metoda navržena. Ona se vlastně jmenuje
blbě. Její jméno by mělo být odvozeno spíš z myšlenky
"hodnota v boolovském kontextu". Ale vznikla v době,
kdy Python místo True a False používal ještě 0 a != 0
(jako C). Pak nepotřebuji pomocnou funkci, ale objekt
můžu použít k testování přesně stejným způsobem, jako
bylo původně zamýšleno:

    ipaddr = IP("192.168.34536.45")
    ....
    if not ipaddr:
        print "zadavas blby vstup"

Chování v boolovském kontextu implementované
metodou __nozero__ navíc umožňuje dynamicky měnit
"platnost" objektu podle potřeby.

Teď k výjimkám. Souhlasím s názorem, že výjimky
by se měly vyskytovat výjimečně. Ale spíše jde o to,
že se výjimečným způsobem ošetřují.

Co se týká výjimky StopIteration, tu považuji spíš
za výjimečnou ;) Jde o to, že samotný cyklus for
je v Pythonu proti "klasickým kompilovaným" jazykům
trochu výjimečný. Není to počítaný cyklus. Je to
zobecněný cyklus přes sekvenci. Existence StopIteration
přestavuje jednu z mála možností, ja mohou všechny možné
iterace dát najevo svůj konec (různé kontejnery, 
generátory...)

A co se týká programování s výjimkami a bez výjimek, 
je to otázka změněného přístupu k tvorbě programu
(podle mého k lepšímu). Když to srovnáváte s goto...

Dříve "neřízené" používání goto způsobovalo těžko
řešitelné problémy. Postupně to vedlo k "objevu"
strukturovaného programování (Wirth jako představitel).
Pořád ale bylo založeno na jednoduchém toku řízení.
Proto bylo možné "následně" testovat, jak to dopadlo
před chvílí.

Ve školních příkladech se často "testování jak to 
dopadlo" pro jednoduchost vynechávalo... protože
to zkrátka vede k zaplevelení kódu smetím, které
není užitečné z hlediska abstraktního uvažování
o problému. Jenže v praxi právě k tomuto jevu dochází
a programy se stávají hůře čitelné (se všemi
důsledky, jako třeba vznik dalších chyb díky bobtnání
kódu). To testování se taky muselo dělat otrocky.
Muselo se myslet na všechny možné situace, které
mohly selhat. Při rozsáhlejším programu je to 
na mašlu.

Objektové programování představuje další změnu
pohledu ve smyslu "spolupráce kooperujících objektů".
A i když se o tom programátoři v praxi zatím 
tak moc neuvažují, znamená to "potenciálně paralelní
činnost" těch objektů. Potom už je velmi těžké
uvažovat v kategoriích co bylo dříve a co později. 
Umělá serializace akcí vede k navození situace, 
kdy by se uplatnil Amdahlův zákon (úzké hrdlo
paralelismu). Výjimka je v takovém případě výhodným
komunikačním prostředkem, který bude fungovat 
i v paralelním prostředí. A opět, výjimečný není
samotný objekt výjimky, ale způsob, jakým je 
jeho existence zpracována.

V jazycích typu C++ získaly kdysi výjimky přívlastek
těžkopádného nástroje. Ale bylo to proto, že existovalo
méně zkušeností s tím, jak jsou užitečné a obtížně
nahraditelné. A taky to souviselo s vývojem překladačů
a s generováním kompilovaného kódu. A taky, v C/C++
se vše měřilo na mikrosekundy a vše je velmi rychlé.
Nutná složitost se proto někdy neoprávněně zaměňovala
za pomalou těžkopádnost.

Ten změněný přístup při návrhu aplikace by se dal
shrnout ve stylu: Naprogramuji to tak, jak by to mělo
fungovat v ideálním případě a pak uvidíme. Selhání 
se mohou ošetřit "bokem".

A ještě jedna výhoda výjimek. Když zapomenu něco 
otestovat v ifech (klasicky), může to krachnout velmi
nepříjemně. Když někde neobsloužím výjimku, můžu ji
krásně obsloužit v hlavní funkci (main).

Mějte se krásně,
   pepr


>---------------------------------------------------------
>Od: David Rohleder
>Přijato: 24.3.2010 9:55:53
>Předmět: Re: [python] nevznik objektu
>
>Vladimir Macek píše v Út 23. 03. 2010 v 23:51 +0100:
>
>> On 19.3.2010 00:04, Jirka Vejrazka wrote:
>
>> > Davide, smir se s tim. Vyjimky jsou v Pythonu zavedeny, chapany a
>
>> > podporovany zpusob reagovani na chybove stavy, zejmena na
>
>> > neocekavana data.
>
>> 
>
>> A i to je zbytecne uzky pohled na to, na co se daji vyjimky pouzivat. Za
>
>> prve, nekdy vubec nenesou chybovou informaci, ani nejsou spojeny
>
>> necekanymi daty. Prikladem je built-in
>
>> http://docs.python.org/library/exceptions.html#exceptions.StopIteration
>
>> Tedy vyjimka, kterou iterator indikuje, ze je vyprodano.
>
>> 
>
>> Za druhe, vyjimky jsou normalni objekty, ktere mohou nest libovolna
>
>> data. Jakoby promenne, ale zpusobi zmenu provadeni programu zcela jinym,
>
>> ale predem danym a casto uzitecnym smerem (z vnoreni ven).
>
>
>
>Přesně na to jsem narážel, když jsem říkal, že někdo používá výjimky
>
>jako lepší goto (kterým navíc dokážeš vyskočit z funkce).
>
>
>
>>  Nejcasteji
>
>> skutecne nesou podrobnou informaci o chybe vykonavani, ale nikdo nikoho
>
>> neomezuje v rozsireni tohoto modelu podle aktualnich potreb.
>
>> 
>
>> 
>
>> > Zkus to chvili nechat odlezet, treba se ti to zacne libit :)
>
>> 
>
>> Za tohle se taky velmi primlouvam.
>
>> 
>
>> Davide, podle toho, co pisete, jste na zacatku: Syntaxi a knihovnu treba
>
>> zvladate, ale jeste vas ceka krok prijmouti zpusobu mysleni, ktery
>
>> zkusenemu pythonistovi pomaha dosahnout vynikajici vykonnosti a elegance
>
>> kodu. To neni vycitka, naopak, jsem rad, ze se ucite a my ostatni vam
>
>> radi pomuzeme.
>
>> 
>
>> Jen to, ze predcasne soudite a snazite se roubovat novy pristup na drive
>
>> naucene (coz clovek ma clovek tendenci povazovat za to lepsi), to je
>
>> mirne iritujici.
>
>
>
>Já to nějak nesoudím, akorát si snažím objasnit některé věci. Imho jsou
>
>napřiklad některé z těch syntaktických cukrů špatně - např. odstranění
>
>závorek z generátorů (i*i for i in range(4)). Ne, že by se na to nedalo
>
>zvyknout, akorát to tady trochu přehnali.
>
>
>
>Ještě pořád mně vy pythonu přijdou některé věci poměrně nešikovně
>
>vyřešené, ale to se časem vsákne.
>
>
>
>
>
>
>
>_______________________________________________
>
>Python mailing list
>
>Python na py.cz
>
>http://www.py.cz/mailman/listinfo/python
>
>
>
>


Další informace o konferenci Python