use*_*517 5 python caching decorator python-decorators
我正在尝试为memoize编写python decorator.我几乎没有问题.
..
class memoize:
def __init__(self):
self.cache = {}
def __call__(self, function):
def wrapper(*args, **kwargs):
key = str(function.__name__) + str(args) + str(kwargs)
if key in cache:
return cache[key]
else:
value = function(*args, **kwargs)
cache[key] = value
return value
return wrapper
@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))
Run Code Online (Sandbox Code Playgroud)
我收到了编译错误.
Traceback (most recent call last):
File "memoize.py", line 17, in <module>
@memoize
TypeError: __init__() takes exactly 1 argument (2 given)
Run Code Online (Sandbox Code Playgroud)
@decorator
只是一个语法糖func = decorator(func)
.所以这里有一个区别:(1)
@decorator
def func():
...
Run Code Online (Sandbox Code Playgroud)
和...一样
func = decorator(func) # Just call of __init__
func(...) # Call of decorator.__call__
Run Code Online (Sandbox Code Playgroud)
但(2)
@decorator(some_param)
def func():
...
Run Code Online (Sandbox Code Playgroud)
类似于
# Call of __init__ plus call of __call__
func = decorator(some_param)(func)
# Call of closure returned by decorator.__call__
func(...)
Run Code Online (Sandbox Code Playgroud)
您已经为(2)语法实现了装饰器接受参数,但在使用它们时不提供它们,如示例(1)所示.这就是为什么__init__
抱怨,它接受func
作为第二个论点.
你应该写self.cache
一个wrapper
闭包,所以wrapper
会引用相应的decorator
对象.写入只会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)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1274 次 |
最近记录: |