Násobky a delitele s dekorátorom

Mechanizmus dekorátorov

V projekte násobky a delitele sme porušili zásadu neduplikovania kódu. Vo views.py sa opakovala kontrola parametra cislo.

Potrebujeme nejako vytiahnuť spoločný kód von z views.

Toto je možné vyriešiť niekoľkými spôsobmi, jeden elegantný je tu.

Využijeme to, že funkcia v pythone je objekt ako každý iný.

Pozrite sa na tento kód:

   1 def skontroluj_cislo(f):
   2 
   3     # * __dekorovane_f je funkcia s dvomi premennymi
   4     #   ocakava, ze v nadradenom prostredi je nastavena premenna f
   5  
   6     def __dekorovane_f(request,cislo):
   7         
   8         # cislo je retazec
   9         # musime ho previest na int
  10         # treba kontrolovat vstup uzivatela! 
  11         try:
  12             cislo_int=int(cislo)
  13         except ValueError:
  14             return chyba("%s sa nepodarilo previest na cislo" % cislo)
  15         if cislo_int<0:
  16             return chyba("cislo %d je zaporne" % cislo_int)
  17         return f(request,cislo_int)
  18 
  19     return __dekorovane_f

skontroluj_cislo je funkcia druhého rádu -- ako parameter dostáva funkciu dvoch premenných a vracia funkciu dvoch premenných. Vrátená funkcia robí to isté ako pôvodná, ale predtým skontroluje druhý parameter, a ak je chybný, vráti chybu.

Teraz môžeme zmeniť funkciu nasobky takto:

   1 # * Toto je povodna funkcia nasobky, z ktorej sme vyhodili
   2 #   kontrolu cisla
   3 # * Ako parameter ocakava uz cislo, nie retazec
   4 def nasobky(request,cislo_int):
   5 
   6     zoz_nasobkov=[]
   7     for i in range(11):
   8         zoz_nasobkov.append(Dvojica(i,i*cislo_int))
   9     c=Context({'cislo':cislo_int,'vysledky':zoz_nasobkov})
  10     t=loader.get_template("nasobky.html")
  11     return HttpResponse(t.render(c))
  12 
  13 # * Blizime sa k pointe:
  14 # * Nasledujuci riadok obohati funkciu nasobky 
  15 #   o kontrolu parametra cislo.
  16 nasobky=skontroluj_cislo(nasobky)

A podobne upravíme funkciu delitele.

Celý projekt je tu: nasobky_a_delitele_v2.tar.gz.

Špeciálna syntax pre dekorátory

Horeuvedený vzor považovali autori Pythonu za dostatočne dôležitý na to, aby mu vyhradili špeciálnu syntax. Nasledujúci kód v má v zásade rovnakú funkciu ako predošlý, líši sa iba syntaxou. Všimnite si, že špeciálna syntax sa nachádza pred funkciou, takže ju čitateľ kódu neprehliadne.

   1 # Teraz pouzijeme specialnu syntax, ktora zabezpeci
   2 # obalenie funkcie dekoratorom
   3 @skontroluj_cislo
   4 def nasobky(request,cislo_int):
   5 
   6     zoz_nasobkov=[]
   7     for i in range(11):
   8         zoz_nasobkov.append(Dvojica(i,i*cislo_int))
   9     c=Context({'cislo':cislo_int,'vysledky':zoz_nasobkov})
  10     t=loader.get_template("nasobky.html")
  11     return HttpResponse(t.render(c))

Verzia so špeciálnou syntaxou je tu :nasobky_a_delitele_v2.1.tar.gz

Viac o dekorátoroch

Horeuvedený text vysvetľuje iba podstatu veci, ak sa chcete dozvedieť o dekorátoroch v Pythone viac, googlite.

Django poskytuje niekoľko dekorátorov, ktoré slúžia na dekoráciu views a (typicky) kontrolujú request, či spĺňa nejakú predbežnú podmienku predtým, ako vykonajú normálny kód view. Napríklad login_required a podobne.

KMaDGWiki: ProgramovanieInternetovychAplikacii/NasobkyADeliteleV2 (last edited 2009-03-03 11:05:02 by 92)