[python] Statické metody v Pythonu

Petr Prikryl PrikrylP na skil.cz
Čtvrtek Listopad 9 09:11:23 CET 2006


> > zem_uhel + "30N54"
> >
> > typicky dosahuje přetížením operátoru + a typicky se
> > implementuje tak, že se na místě druhého argumentu očekává
> > konstantní reference a třídu zemepisny_uhel. Jenže u třídy
> > zemepisny_uhel by se v takovém případě typicky definoval
> > konstruktor, který bere odkaz na konstantní string a může
> > se tam tedy dosadit i literál. Překladač pak automaticky
> > udělá tohle:
> >
> > zem_uhel + zemepisny_uhel("30N54")
>  
> No, C++ je velmi flexibilní jazyk, takže buď C++ zavolá
> konstruktor, a nebo operátor +, kde druhý parametr je
> string, pokud takový existuje. Ta první varianta s voláním
> konstruktoru je "drahá", tedy z nouze ctnost, protože se
> zbytečně vytváří dočasná instance, a pak zase ruší. Operátor
> + to většinou dokáže efektivněji s mnohem menší režií.

Ano. Ale toto je otázka návrhu. Typicky se definuje operátor
pro sčítání (operator+() nebo __add__()), který pracuje s
argumentem stejné třídy, jako je sám objekt. V budoucnu si můžu
vymyslet další konverze, ze kterých vypadne úhel. Z hlediska
údržby je lepší, když se speciality dělají zvenku. Je tedy
lepší venku převést string zeměpisné šířky na úhel a
dosadit.

> [...] ale vzniká tu
> instance třídy uhel, která vlastně vzniknout nemusí.
> Řekněme, že je to takový relikt v mém myšlení, který mě nutí
> se občas zabývat efektivitou programu a který mi říká, že
> vytvoření instance třídy uhel není potřeba. Proto jsem
> zavedl tu statickou metodu a upravil jsem __add__ tak, aby
> přijímal i čísla a stringy.

Jedna věc je strojová efektivita a druhá věc je jak je to
mentálně uchopitelné, tj. kolik to dá práce mozku
programátora (pokud tedy neprogramuje srdcem ;)

The Zen of Python k tomu všemu může říci (výběr):

Explicit is better than implicit.
Simple is better than complex.
Readability counts.
Special cases aren't special enough to break the rules.
In the face of ambiguity, refuse the temptation to guess.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.

> [...]
> A tohle udělá to samé, ale vytvoří se (a pak posléze 
> zruší) navíc instance třidy uhel:
> 
> u4 = u1 + uhel(3.0)
> 
> Prostě nevím a netuším, jestli tuhle režii vytvoření
> instance navíc mám vzít v úvahu. Pokud jí připustím, mám
> asi čistější kód, pokud zase pomůžu metodě __add__, aby
> uměla sečíst číslo přímo, mám efektivnější kód. Naproti
> tomu zase hrozí, že sečtu něco, co se jako číslo bude
> tvářit a významově to nemá s úhlem nic společného a můžu
> hledat chyby. Nevím, který postup je správný, asi každý má
> něco.

Viz výše. Navíc "In the face of ambiguity, refuse the
temptation to guess." mívá pokračování "změř to".

Obvykle se taky projevuje dualita mezi daty a kódem:
Složitější kód, jednodušší datové struktury a naopak.
Složitější kód může vést k úspoře paměti, ale obvykle také
ke zvýšení časové náročnosti. Složitější datové struktury...

> [...] Jenže u mě ta statická metoda pro vytvoření
> úhlu vypadá takto a taky sežere až neuvěřitelně divoké
> definice úhlů od zadání úhlu v radiánech až po různé se
> stupni, minutami, atd. [...]
 
Asi bych raději místo statické metody použil obyčejnou
funkci ve stejném modulu. Pokud by potomek potřeboval něco
jiného, předefinoval by si příslušnou metodu tak, aby volala
jinou funkci. Zadarmo bych tím také získal přístup k oné
funkci bez závislosti na používání tříd, které ji používají
(tj. např převod z řetězce na radiány).
 
> Uf, dekorátory mě zajímají. V manuálu jsem našel tak akorát
> velké nic, takže informace na toto téma vítám.

Ony dekorátory taky nic moc nedělají. Je to jen takový
"syntactic sugar" -- to tvrdí "opravdoví programátoři"
opovržlivě. Na druhou stranu, právě takové věci dělají
použití jazyka elegantním. Přetěžování operátorů je taky
syntaktický cukřík, ale jak pěkně se s tím pak pracuje!
(Tedy pokud se to nachystá správně.)

pepr


Další informace o konferenci Python