Dekorátor ako trieda
Od dekorátora skontroluj_cislo chceme takéto správanie sa:
Ak f je funkcia z dvomi parametrami (request,cislo_int), skontroluj_cislo(f) má vrátiť volateľný objekt tiež s dvomi parametrami (request,cislo), ktorý vykoná patričné kontroly parametra cislo, prevedie ho na int a ak všeko sedí, zavolá f.
Iný spôsob ako toto zrealizovať je definovať dekorátor ako triedu.
1 class skontroluj_cislo(object):
2 """
3 * Teraz spravime dekorator ako triedu
4 * Jej instancie su callable objekty, ktore sa chovaju
5 * ako dekorovane funkcie
6 * Konstruktor ocakava `f` ako parameter
7 * Ako parameter ocakava funkciu `f(request,cislo)`
8 * Jeho navratovou hodnotou je funkcia, ktora skontroluje
9 cislo, ak je chybne vrati chybu, a ak je v poriadku,
10 zavola `f`.
11 """
12
13 def __init__(self,f):
14 self.f=f
15
16 def __call__(self,request,cislo):
17
18 # cislo je retazec
19 # musime ho previest na int
20 # treba kontrolovat vstup uzivatela!
21 try:
22 cislo_int=int(cislo)
23 except ValueError:
24 return chyba("%s sa nepodarilo previest na cislo" % cislo)
25 if cislo_int<0:
26 return chyba("cislo %d je zaporne" % cislo_int)
27 return self.f(request,cislo_int)
Ako to funguje
Uvedomme si, že python pri dekorovaní urobí nasobky=skontroluj_cislo(nasobky), čo teraz znamená vytvorenie inštancie triedy skontroluj_cislo, ktorá sa volá nasobky. To znamená, že sa zavolá __init___. Ak sa potom narazí na volanie nasobky(request,cislo), python zistí, že objekt nasobky je inštanciou triedy, ktorá implementuje metódu ___call___. To znamená, že inštancie tejto triedy sú volateľné.
Dôjde teda nakoniec k volaniu skontroluj_cislo.__call__(nasobky,request,cislo).