[python] Dekorátor

Jakub Vysoky jakub na borka.cz
Pondělí Únor 21 13:56:57 CET 2011


jenom bych rad doplnil, zed pythoni syntaxe

 @muj_dekorator
 def moje_funkce(*args): pass

je jenom syntakticky cukr a znamena to:

 moje_funkce = muj_dekorator(moje_funkce)

z cehoz je mozna mnohem jasnejsi, jak dekorator funguje.
alespon mne to tak dava vetsi smysl ;))

jakub..

ps: dekorator nemusi byt jenom funkce, je to zkratka objekt obalujici
jiny objekt


2011/2/20 Róbert Čerňanský <hslists na zoznam.sk>:
> On Wed, 16 Feb 2011 06:23:07 -0800 (PST)
> Radek <radek.hnilica na gmail.com> wrote:
>
>> Byl by tady někdo, kdo by mě mohl odkázat na rozumný studijní
>> materiál, podtrhuji rozumný, ze kterého bych byl schopen pochopit, jak
>> funguje dekorátor který definuju jako třídu.  S dekorátory jako
>> funkcemi jsem se nějak popasoval, tedy aspoň si to myslim, ale u té
>> třídy je to pro mě černá magie.
>
> S tými rozumnými materiálmi je to bieda.  Hlavne sa mi zdá, že
> oficiálny Python Tutorial akosi zaostáva.  Pri niekoľkonásobnom
> prečítaní relevantných (a roztrúsených) častí oficiálnej dokumentácie
> [1], [2], [3] a PEP 318 [4] sa to akosi dá pochopiť.  Pokúsim sa to
> vysvetliť nižsie.
>
>> Pokud nemá dekorátor parametry, tak se zdá že to nějak chápu.  Do
>> __init__ je předána dekorovaná fuknce a do __call__ jsou pak předávány
>> argumenty té funkce viz:
>>
>> class mydec:
>>     def __init__(self, fce):
>>         self.fce = fce   # Store, we will use it in __call__
>>
>>     def __call__(self, *args, **kwds):
>>         ....pre
>>         result = self.fce(*args, **kwds)
>>         .....post
>>         return result
>>
>> @mydec
>> def myfunc(*args, **kwds):
>>     pass
>>
>> Ale pokud má mít dekorátor parametry, tak jsem sice našel/zkonstruoval
>> kód který se zdá fungovat, ale plně mu nerozumím.
> [...]
>> Jen tím že chci aby měl dekorátor parametry, se tak radikálně změní
>> kód dekorátoru.
>> Potřeboval bych nějak po lopatě vědět, co se uvnitř děje, protože
>> cítím že ty dekorátory budu určitě používat ještě mnohem divočeji.
>
> Vo všeobecnosti je dekorátor funkcia, ktorá vracia funkciu.  V Pythone
> je dekorátor "niečo, čo sa dá zavolať" a po zavolaní to vráti tiež
> "niečo, čo sa dá zavolať".  To "niečo, čo sa dá zavolať" je akýkoľvek
> objekt, ktorý má metódu __call__() - čiže funkcia; trieda; inštancia
> tredy, ktorá definuje __call__(); jedným slovom callable.  To prvé
> callable reprezentuje samotný dekorátor a to druhé callable
> reprezentuje, *v prípade dekorátora bez parametrov*, odekorovanú
> funkciu (čize funkciu, ktorá už je "oblečená" do dekorátora).
>
> Dekorátor (to, čo je za @) je volaný pri *definícii* funkcie, teda nie
> pri jej zavolaní.  Pri tomto volaní sa vráti uz spomínané druhé
> callable, ktoré reprezentuje odekorovanú funkciu (v prípade dekorátora
> bez parametrov).  To je potom volané zakaždým, keď je volaná
> dekorovaná funkcia (čiže tá, ktorá má nad sebou @).
>
> _Dekorátor bez parametrov_, je zavolaný s jedným parametrom a tým je
> dekorovaná funkcia.
>
> Čiže keď zoberieme Tvoj príklad dekorátora bez parametrov, tak mydec
> je zavolaný pri definícii myfunc() a dostane myfunc ako parameter.
> Keď zoberieme do úvahy, že mydec je trieda, tak jej zavolanie vlastne
> znamená vytvorenie inštancie.  Táto vzniknutá inštancia má __call__()
> a teda spĺňa podmnienku, že je callable.  Vniknutá inštancia teda
> reprezentuje odekorovanú myfunc() a jej metóda __call__() je zavolaná
> pri každom volaní myfunc().
>
> _Dekorátor s parametrami_, je zavolaný iba s tými parametrami, s
> ktorými bol nadefinovaný.  Čiže *nedostane dekorovanú funkciu*.
> Callable, ktoré takýto dekorátor vráti reprezentuje *ďalší dekorátor*.
> Tento ďalší dekorátor, je už "normálny" dekorátor bez parametrov
> popísaný vyššie.  Je zavolaný tiež pri definícii funkcie (hneď za
> dekorátorom s parametrami, ktorý ho vrátil) a dostane dekorovanú
> funkciu ako parameter.
>
> Dúfam, že som Ťa ešte viac nepoplietol. ;-)
>
> [1] - http://docs.python.org/py3k/glossary.html#term-decorator
> [2] -
> http://docs.python.org/py3k/reference/compound_stmts.html#function
> [3] -
> http://docs.python.org/py3k/whatsnew/2.4.html?highlight=decorator
>
> Robo
>
>
> --
> Robert Cernansky
> E-mail: hslists na zoznam.sk
> Jabber: hs na jabber.sk
> _______________________________________________
> Python mailing list
> Python na py.cz
> http://www.py.cz/mailman/listinfo/python



-- 
Jakub Vysoky

mob: +420 605 852 377
jab: jakub.vysoky na gmail.com
icq: 109248375
twit: https://twitter.com/kvbik


Další informace o konferenci Python