>您应该记住@decorator只是func = decorator(func)的语法糖.所以这里有一个区别:
(1)
@decorator
def func():
...
和…一样
func = decorator(func) # Just call of __init__
func(...) # Call of decorator.__call__
但(2)
@decorator(some_param)
def func():
...
类似于
# Call of __init__ plus call of __call__
func = decorator(some_param)(func)
# Call of closure returned by decorator.__call__
func(...)
>您已经为(2)语法实现了装饰器接受参数,但在使用它们时不提供它们,如示例(1)所示.这就是为什么__init__抱怨,它接收func作为第二个参数.
>您应该在包装器闭包中编写self.cache,因此包装器将引用相应的装饰器对象.写入缓存将导致全局变量搜索,因此将失败.
UPD:我改变你的代码接近(1):
class memoize:
def __init__(self, function):
self.cache = {}
self.function = function
def __call__(self, *args, **kwargs):
key = str(args) + str(kwargs)
if key in self.cache:
return self.cache[key]
value = self.function(*args, **kwargs)
self.cache[key] = value
return value
@memoize
def fib(n):
if n in (0, 1):
return 1
else:
return fib(n-1) + fib(n-2)
for i in range(0, 10):
print(fib(i))
print(fib.cache)