Decoratori
Le funzioni, essendo oggetti, possono essere passate come parametro di un’altra funzione.
def hello(name):
return f"hello {name}"
def welcome(name):
return f"welcome {name}"
def greetBob(function):
return function("Bob")
print(greetBob(hello)) # hello Bob
print(greetBob(welcome)) # welcome BobQuesto comportamento ci può venire utile per essere sicuri che alcune funzioni vengano chiamate con i giusti parametri, o per calcolare il tempo di esecuzione di una funzione.
from time import time
def CalculateTime(func): # decoratore
def timer(*args, **kargs):
start_time = int(round(time() * 1000000))
res = func(*args, *kargs)
stop_time = int(round(time() * 1000000))
print(f"Elapsed time {stop_time-start_time}\u03BCs")
return res
return timer
@CalculateTime # decorazione
def calcola(x, y):
return x+y
# è equivalente a: CalculateTime(calcola)Classi come decoratori
Le classi possono essere anche utilizzate come decoratori.
class D:
def __init__(self, type):
self.type = type
def __call__(self, inappname):
def getInAppFinalID():
return self.type + "." + inappname()
return getInAppFinalID
@D("MAINGROUPID")
def inAppID():
return "com.team.appname"D prende come parametro init una stringa type, istanzia l’oggetto e passa la funzione inAppID come parametro alla funzione __call__ di D, che ritorna la funzione getInAppFinalID() e la assegna alla funzione inAppID. Quando si chiama la funzione inAppID, quindi, in realtà si sta chiamando la funzione getInAppFinalID, che utilizza inAppID come parametro.
Decorare una classe
Non solo i metodi, ma anche le classi possono essere decorate. La funzione prende quindi in input una classe, e restituisce un’altra classe (la classe decorata) in output.
def SCD(C):
C.newmethod = lambda self, x: self.z+x
return C
@SCD
class B:
z = 3
l = B()
l.newmethod(23)