miercuri, 2 septembrie 2009

Python Decorators

In unele privinte decorator-urile in python sunt asemanatoare cu annotarile din java. Totusi, ele ofera o flexibilitate sporita si o usurinta remarcabila in implementare. Modul de implementare al unui decorator este valabil pentru Python 2.6+. Exemplul de mai jos este luat din documentatia python: implementarea pattern-ului Singleton.

class singleton:
def __init__(self, aClass):
self.__instance = None
self.__aClass = aClass
def __call__(self, *args):
if not self.__instance:
self.__instance = self.__aClass(*args)
return self.__instance

@singleton
class TestSingleton:
def __init__(self):
print("Instantiez")

objTest = TestSingleton()
objTest = TestSingleton()

Pornind de la acest exemplu, voi explica bazele unui decorator. Un decorator este orice clasa care are metoda __init__ cu un parametru si metoda __call__. Parametrul de la metoda __init__ reprezinta o clasa sau o functie(depinde de scop: decorator de clasa sau de functie). De obicei in metoda __init__ se va referinta la clasa iar in metoda __call__ vine logica efectiva. Referitor la logica codului de mai sus, daca va uitati in __dict__ clasei veti putea observa _singleton__instance. In principiu toate atributele unui decorator sunt salvate in dictionarul clasei si urmeaza conventia de name mangling pentru atributele "private".

In practica am folosit decorator pentru a implementa mecanisme de cache pentru o clasa. Exista multe aplicatii pe care vi le puteti imagina. De obicei, utilizarea decorators sporeste lizibilitatea codului.