我在阅读decorators,并试图将这两个示例混合起来,使它们成为类decorator而不是常规函数。第一种方法只允许每个参数运行一次函数,第二种方法计算运行该函数的次数。它们都很好地分开工作,但是当我试图同时用它们来装饰一个简单的函数时,它失败了。。。或者不是真的失败,而是打印出意外的错误结果。我读了一些书,发现functools模块可以帮上忙,但我不知道该怎么做。在
from functools import update_wrapper
class Memoize:
def __init__(self, func):
self.func = func
self.memo = dict()
update_wrapper(self, func)
def __call__(self, *args):
if args not in self.memo:
self.memo[args] = self.func(args)
else:
print("cls decorator. You have printed this before")
return self.memo[args]
class CallCounter:
def __init__(self, func):
self.func = func
self.calls = 0
self.__name__ = func.__name__
update_wrapper(self, func)
def __call__(self, *args, **kwargs):
self.calls += 1
return self.func(*args, **kwargs)
@Memoize
@CallCounter
def doubleprint(x):
for elem in x:
print(elem + " " + elem)
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Bye')
print(doubleprint.calls)
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Hello')
doubleprint('Bye')
print(doubleprint.calls)
默认情况下,
update_wrapper
更新包装类中的__dict__
。因此,Memoize
中的func
被CallCounter
中的func
覆盖,这意味着Memoize
直接调用你的doubleprint()
函数,而从不调用CallCounter
。在您可以通过执行以下操作来解决此问题:
^{pr2}$它不会将},依此类推
__dict__
从CallCounter
复制到Memoize
实例,但仍然会复制{要访问
CallCounter
类,您需要:但您需要上面的修复程序,否则它将始终打印
0
(因为它从未被调用)。在相关问题 更多 >
编程相关推荐