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?