【发布时间】:2018-12-10 19:16:00
【问题描述】:
我想在类方法上使用 memorize 装饰器。 cExample.pri() 打电话给self.text() 但memorize 似乎不知道self。当memorize 调用self.func(*key) 时,它缺少cExample obj,因此它抱怨缺少args。
如何更改这个 memorize 装饰器,以便它能够将调用者的 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'
【问题讨论】:
-
内置的
functools.lru_cache似乎没有这个问题,可以考虑使用 -
从
memorize内部访问cExample 的self很棘手,因为通常的方法绑定过程只对函数对象自动起作用,而memorize是一个字典,而不是一个函数。您可以通过覆盖 memorize 的__get__来实现自己的方法绑定,但是 IMO 这样做非常复杂,以至于您失去了使您的原始想法首先具有吸引力的简洁性。到时候还不如写一个普通的基于函数的装饰器。 -
您想要一个缓存来处理所有
cExample实例,还是希望每个实例都有自己的缓存?如果是前者,您是否希望缓存忽略self?
标签: python python-3.x python-decorators