PDA

View Full Version : [python] metaclassi & decoratori


snowx
22-09-2011, 11:32
dovrei impostare una metaclasse che aggiunge un decoratore ad un metodo della classe principale.
supponendo che nella classe principale abbia un metodo print_nome creo una metaclasse che fa classdict['print_nome'] = deco, dove deco č il mio decoratore, esatto?

cdimauro
22-09-2011, 13:59
Per queste cose ti conviene utilizzare i pių semplici decoratori di classe, piuttosto che ricorrere alle metaclassi.

snowx
22-09-2011, 14:06
Per queste cose ti conviene utilizzare i pių semplici decoratori di classe, piuttosto che ricorrere alle metaclassi.
č un'esercizio in preparazione per un'esame

cdimauro
22-09-2011, 21:20
Ho capito. In questo caso ti basta, nella metaclasse, recuperare il metodo voluto dal dizionario dei metodi della classe in oggetto, richiamare il decoratore passandogli il metodo, inserirne il risultato del dizionario precedente.

snowx
23-09-2011, 10:22
ho risolto cosė

def deco(func):
print('entro deco')
count=0
def onCall(*args,**kargs):
nonlocal count
count+=1
print('chiamata numero %s' %count)
if count ==3:
return func(*args,**kargs)
return onCall

class Meta(type):
def __new__(cls,classname,super,classdict):
print('cls',cls,'clname',classname,'super',super,'dict',classdict)
classdict['n_eta']=deco(classdict['n_eta'])
return type.__new__(cls,classname,super,classdict)

class Person(metaclass=Meta):
def __init__(self,n,c,e):
self.nome=n
self.cognome=c
self.eta=e

def n_eta(self,a):
self.eta=int(self.eta)+a
return(self.eta)

def __str__(self):
return "il mio nome e' {0} cognome {1} eta' {2} ".format(self.nome,self.cognome,self.eta)

if __name__ == "__main__":
p=Person('tizio','caio','3')
print(p)
p.n_eta(5)
print(p)
p.n_eta(8)
print(p)
p.n_eta(7)
print(p)

ci sono altre soluzioni pių eleganti?

cdimauro
23-09-2011, 14:06
Sė, i decoratori di classe. Personalmente non li ho mai usati, ma la sintassi č identica a quella dei normali decoratori di funzioni/metodi, per cui č decisamente pių pulita, elegante e leggibile.