Radek (Wednesday 16 of February 2011 15:23:07): > nejdřív bych se uvedl, jsem takový opakovaný začátečník, k Pythonu > jsem naposled přičichl možná před osmi lety a nic moc. Teď, asi tři > měsíce zpátky jsem se k němu vrátil, protože si hraju s GAE/P. Přes > všechny problémy se zkouším prokousávat, ikdyž python bolí, Něco děláš špatně. Kde to bolí?
> 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. Vtip je v tom že se ve skutečnosti kód nijak nemění. Intuitivní představa že parametry v závorkách by měly být předány dekorátoru je jen optický klam. Pokud mám dekorátor jménem "spam" @spam pak @spam("dirt") je ve skutečnosti: @spam.__call__("dirt") A skutečný dekorátor je výsledek tohoto výrazu. Proč tak složitě? Chování dekorátorů je koupodivu logičtější když zapomeneš na triviální jednoslovné dekorátory a zauvažuješ jak se interpret popere se složitějšími výrazy. Představ si například dekorátor který je metodou objektu: @hamClass.spam("dirt") Interpret ve skutečnosti uvidí toto: hamClass.__getAttr__("spam").__call__("dirt") Tady už není tak lehké říci co je samotný výraz a co by "intutivně" měly být parametry výsledného dekorátoru. Ještě lepší to je pokud mám funkci která vrací dekorátor: @ham("dirt").spam("dirt") je vlastně @ham.__call__("dirt").__call__("dirt") Proč by prakticky stejný token jednou měl být klasické volání funkce a podruhé dekorátor? A pokud vymyslíš nějaké složité pravidlo jak to do sebe poznat: @ham() je dekorátor bez parametrů nebo funkce bez parametrů která vrací dekorátor? Ergo "naivní" pohled na parametry dekorátoru by fungoval pokud by dekorátory byly omezeny jen na primitivní výrazy, což by byla škoda. Python tedy považuje všechno za zavináčem za výraz který bude interpretován CELÝ a dekorátor je výsledek tohoto výrazu, včetně volání funkcí. To má krásný efekt že dekorátor je běžná funkce (tj. jakýkoliv objekt s metodou __call__()). Objekty s tímhle nemají nic společného, pouze jmenný prostor uzávěry nahrazují jmenným prostorem instance (metoda __call__ třídy vrací instanci) Osobně považuji použití objektů k dekoraci za nešťastné. Metoda "uzávěra v uzávěře" sice vypadá zezačátku děsivě, ale je aspoň přímočará a dá se pochopit co se děje uvnitř. Objekty jen nahradí jednu složitost jinou (kolik lidí chápe nuance metod __call__, __new__ a __init__?). _______________________________________________ Python mailing list Python@py.cz http://www.py.cz/mailman/listinfo/python