[Python] Metodi decorati con classi

Pietro Battiston me a pietrobattiston.it
Lun 22 Apr 2013 08:58:39 CEST


Salve a tutti,

sto scoprendo il meraviglioso mondo dei decoratori. Imparando ad
apprezzare l'eleganza di un


def myDecoratorF(func):
    def _decorator(self, *args):
        print "self is", self
        print "args are", args
        print "inside myDecoratorF()"
        return func(self, *args)
    return _decorator

class Decorata:
    @myDecoratorF
    def anotherFunction(self):
        print "inside anotherFunction()"


e la poesia di un

class myDecoratorC(object):
    def __init__(self, f):
        print "inside myDecoratorC.__init__()"
        self.f = f

    def __call__(self, *args):
        print "self is", self
        print "args are", args
        print "inside myDecoratorC.__call__()"
        self.f( *args )


@myDecoratorC
def aFunction(*args):
    print "inside aFunction()"


Il problema è: come faccio ad unire gli approcci, ovvero ad avere un
metodo decorato da una classe? O meglio: farlo è facile, ma nel seguente
codice riassuntivo:


class myDecoratorC(object):
    def __init__(self, f):
        print "inside myDecoratorC.__init__()"
        self.f = f

    def __call__(self, *args):
        print "self is", self
        print "args are", args
        print "inside myDecoratorC.__call__()"

def myDecoratorF(func):
    def _decorator(self, *args):
        print "self is", self
        print "args are", args
        print "inside myDecoratorF()"
        return func(self, *args)
    return _decorator


class Decorata:
    @myDecoratorC
    def aFunction(self):
        print "inside aFunction()"
    
    @myDecoratorF
    def anotherFunction(self):
        print "inside anotherFunction()"


a = Decorata()
a.aFunction()
a.anotherFunction()


Il mio problema è semplicemente che i due
    print "self is", self
stampano due cose diverse. Nel decoratore funzione, "self" è un'istanza
della classe decorata, nel decoratore funzione, è un'istanza del
decoratore stesso (e "args" continua ad essere vuoto!). Come faccio a
recuperare, dal __call__ del decoratore classe, l'istanza di "Decorata"
a cui è relativa la chiamata ("a" nel codice sopra)? Se non riesco a
recuperarlo, non posso chiamare il metodo decorato...

Mi sono letto quel che ho trovato di documentazione sui decoratori, ma
sull'uso di classi come decoratori non ne ho trovata! E non ho trovato
neanche esempi che le usano per decorare metodi di altre classi...

grazie

Pietro



Maggiori informazioni sulla lista Python