19 Stimmen

Python-Dekorator, self wird verwechselt

Ich bin neu in Python Dekorateure (wow, tolles Feature!), und ich habe Schwierigkeiten, die folgenden zu arbeiten, weil die self Die Argumentation gerät etwas durcheinander.

#this is the decorator
class cacher(object):

    def __init__(self, f):
        self.f = f
        self.cache = {}

    def __call__(self, *args):
        fname = self.f.__name__
        if (fname not in self.cache):
            self.cache[fname] = self.f(self,*args)
        else:
            print "using cache"
        return self.cache[fname]

class Session(p.Session):

    def __init__(self, user, passw):
        self.pl = p.Session(user, passw)

    @cacher
    def get_something(self):
        print "get_something called with self = %s "% self
        return self.pl.get_something()

s = Session(u,p)
s.get_something()

Wenn ich dies ausführe, erhalte ich:

get_something called with self = <__main__.cacher object at 0x020870F0> 
Traceback:
...
AttributeError: 'cacher' object has no attribute 'pl'

für die Zeile, in der ich self.cache[fname] = self.f(self,*args)

Das Problem - Offensichtlich besteht das Problem darin, dass self ist das Cacher-Objekt anstelle einer Session-Instanz, die tatsächlich keine pl Attribut. Ich kann jedoch nicht herausfinden, wie ich das Problem lösen kann.

Lösungen, die ich in Betracht gezogen habe, aber nicht verwenden kann - Ich dachte daran, die Dekoratorklasse eine Funktion anstelle eines Wertes zurückgeben zu lassen (wie in Abschnitt 2.1 dieser Artikel ), so dass self im richtigen Kontext ausgewertet wird, aber das ist nicht möglich, da mein Dekorator als Klasse implementiert ist und die eingebaute __call__ Methode. Dann dachte ich no eine Klasse für meinen Dekorator verwenden, so dass ich die __call__Methode nicht benötige, aber ich kann das nicht tun, weil ich den Zustand zwischen den Aufrufen des Dekorators beibehalten muss (d.h. um zu verfolgen, was in der self.cache Attribut).

Frage - Neben der Verwendung einer globalen cache Wörterbuchvariable (was ich nicht ausprobiert habe, aber annehme, dass es funktioniert), gibt es eine andere Möglichkeit, diesen Dekorator zum Laufen zu bringen?

Edit: diese SO-Frage scheint ähnlich zu sein Dekorieren von Python Klassenmethoden, wie übergebe ich die Instanz an den Dekorator?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X