[python] Dekorátor - prosím pěkně o konzultaci a vysvětlení

Hynek Fabian hynek.fabian na firma.seznam.cz
Středa Květen 9 14:37:29 CEST 2012


> tj. d neni v podstate primo dekorator, ale tovarna, ktera dekorator
> vytvori (1. vnoreni) a ten pak vetsinou obsahuje wrapper puvodni
> funkce (2. vnoreni)

To bych si dovolil trochu rozvést. Důvod je ten, že kód za zavináčem je
platný pythoní výraz se vším všudy. Může tedy to být i něco složitějšího:

@spamClass("dirt").getSpamDeco(someHam, 42)

Jak může interpret poznat jestli je getSpamDeco dekorátor s parametry
nebo fabrická  metoda která vrací parametrizovaný dekorátor?
Příklad se dá najít přímo ve standartní knihovně – property dekorátor má
metody setter a deleter. Tam kde člověk napíše "@x.setter" ovšem
interpret uvidí "x.__getattribute__('setter')" a zase by nevěděl jak si
to má vykládat. Interpret se proto řídí jednoduchým pravidlem – nějaké
dekorátory neřeší a prostě vyhodnotí výraz se vším všudy.
Z hlediska interpretru je tedy řešení výše uvedeného dilematu takové, že
každé takové volání je parametrizovaný dekorátor. Z hlediska
programátora to znamená, že  obskoč s parametrizovaným dekorátorem je
nutné udělat i když by stačilo dekorovat všechno jednou funkcí která by
přebírala parametry.
Druhá vnitřní funkce je už jen klasický wrapper nad samotnou dekorovanou
funkcí.
Celé je to jen důsledek snahy udržet jednoduchou vnitřní logiku
interpretru. Ve výsledku to sice vypadá hrozně, ale dá se to pochopit
aplikací jednoduchých pravidel.
Sám jsem to ocenil až když jsem na narazil na IMO opačný případ – copy
konstruktory v C++. Snaha o "přímočarý" zápis tam vede ke složité logice
uvnitř kompileru a pro mě obtížně předvídatelné chování.

BTW kdysi jsem si napsal "metadekorátor" který na funkci s parametry
aplikoval onen obskoč automaticky. Pokud to nebude někde v archivu
konfery, je to celkem zajímavý domácí úkol na procvičení dekorátorů :-)

Ufff…


Další informace o konferenci Python