我是Python裝飾器(哇,偉大的功能!)的新手,我無法獲得以下工作,因爲self
參數混合起來。Python裝飾器,自我混合
#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()
當我跑,我得到:
get_something called with self = <__main__.cacher object at 0x020870F0>
Traceback:
...
AttributeError: 'cacher' object has no attribute 'pl'
的,我做self.cache[fname] = self.f(self,*args)
問題行 - 很顯然,問題是self
是cacher的對象,而不是的Session實例,它確實沒有pl
屬性。但是我找不到如何解決這個問題。
解決方案,我認爲,但不能使用 - 我想使裝飾類(本article的2.1節等)返回一個函數,而不是一個值,從而self
是在正確的上下文中計算的,但這是不可能的,因爲我的裝飾器是作爲一個類實現的,並使用內置的__call__
方法。然後我想到而不是爲我的裝飾器使用了一個類,這樣我就不需要__call__方法了,但是我不能這樣做,因爲我需要在裝飾器調用之間保持狀態(即用於保持跟蹤self.cache
屬性)。
問題 - 因此,除了使用全局cache
字典變量(我沒有嘗試,但假設將工作),還有沒有其他的方法,使這項工作裝飾?
編輯:這太問題似乎類似Decorating python class methods, how do I pass the instance to the decorator?
您知道這樣,'Session'的所有實例將共享相同的緩存? – 2011-03-29 08:49:56
是的,我還沒有完成代碼,但我粗略地想到給一個額外的會話參數來保存單獨的緩存。 – Rabarberski 2011-03-29 08:55:44