我想在类方法上使用一个记忆装饰器。 cExample.pri()
呼叫self.text()
,但memorize
似乎不了解self
。当memorize
调用self.func(*key)
时,它会丢失cExample
obj,因此会抱怨缺少参数。
如何更改此记忆装饰器,使其能够将调用者的self
传递给函数?
Python3.5.2
class memorize(dict):
def __init__(self, func):
self.func = func
def __call__(self, *args):
return self[args]
def __missing__(self, key):
result = self[key] = self.func(*key)
return result
class cExample():
@memorize
def pri(self, text):
return self.text(text)
def text(self, text):
return text
c = cExample()
print(c.pri('hi'))
输出:
Traceback (most recent call last):
File "x.py", line 23, in <module>
print(c.pri('hi'))
File "x.py", line 7, in __call__
return self[args]
File "x.py", line 11, in __missing__
result = self[key] = self.func(*key)
TypeError: pri() missing 1 required positional argument: 'text'
答案 0 :(得分:1)
您需要将self
(即c
)传递给cExample.pri
(即self.func
)。但是__missing__
不允许您这样做:它只接收密钥。
您可以使用基于函数的装饰器将其重写:
import functools
def memorize2(f):
cache = {}
@functools.wraps(f)
def wrapper(*args):
if args not in cache:
cache[args] = f(*args)
return cache[args]
return wrapper
class cExample():
@memorize2
def pri(self, text):
return self.text(text)
def text(self, text):
return text
c = cExample()
print(c.pri('hi')) # hi
(我正在使用functools.wraps来保留修饰方法的原始名称)。
在这种方法中,self
将作为位置arg传递到wrapper
,并被代理到cExample.pri
。