>您應該記住@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)