记忆装饰器保持存储的值
Memoizing decorator keeping stored values
我有一个如下所示的记忆装饰器:
def memoize(obj):
from functools import wraps
cache = {}
@wraps(obj)
def memoizer(*args, **kwargs):
if args not in cache:
cache[args] = obj(*args, **kwargs)
return cache[args]
return memoizer
但是,我不确定这个函数是否正常工作,因为在我看来它每次调用装饰函数时都会将 cache
重新创建为一个空字典。当我用一个简单的斐波那契函数测试它时,它似乎确实能正确记忆。那么cache
不是每次都重新创建吗?
包括这一行的python wiki has a version:
cache = obj.cache = {}
所以我不确定这是做什么的。我猜想 python 函数是对象,因此它正在创建一个与该函数关联的新属性,并且每次调用该函数时都会公开 available/usable。
在任何一个版本中,如果我重复调用该函数,如在递归定义中或只是通过重复调用,缓存是如何处理的?它是否与函数相关联,是否成为 "global" 变量,或其他什么?
1) 每次调用 memoize()
都会创建一个新的 cache
。但是 memoize()
每个装饰函数只被调用一次。因此每个装饰函数都有自己的 cache
.
2) 关于cache = obj.cache = {}
:
函数也是 Python 中的对象。正如您已经假设的那样,obj.cache = {}
将在包装函数上创建一个新属性。本地缓存对象和包装函数上的缓存属性将指向同一个字典。
这并不是说 cache
是一个全局变量 - 它在 memoize 函数中是局部变量,它是函数的一个属性。
如果您有装饰函数 f
,您可以在全局范围内访问 f.cache
,如果这就是全局变量的意思。
如果您重复调用修饰函数,它将始终访问特定于修饰函数的相同 cache
。
解决内部函数不蜂 "memoized"。
def outer():
# do not add the decorator here!
def inner():
return 5
if(not hasattr(outer, "inner")):
# the "@" decorator is only syntactical sugar,
# we can simply call the decorator function to wrap another function
outer.inner = memoize( inner )
outer.inner()
return outer.inner()
outer()
outer()
我有一个如下所示的记忆装饰器:
def memoize(obj):
from functools import wraps
cache = {}
@wraps(obj)
def memoizer(*args, **kwargs):
if args not in cache:
cache[args] = obj(*args, **kwargs)
return cache[args]
return memoizer
但是,我不确定这个函数是否正常工作,因为在我看来它每次调用装饰函数时都会将 cache
重新创建为一个空字典。当我用一个简单的斐波那契函数测试它时,它似乎确实能正确记忆。那么cache
不是每次都重新创建吗?
包括这一行的python wiki has a version:
cache = obj.cache = {}
所以我不确定这是做什么的。我猜想 python 函数是对象,因此它正在创建一个与该函数关联的新属性,并且每次调用该函数时都会公开 available/usable。
在任何一个版本中,如果我重复调用该函数,如在递归定义中或只是通过重复调用,缓存是如何处理的?它是否与函数相关联,是否成为 "global" 变量,或其他什么?
1) 每次调用 memoize()
都会创建一个新的 cache
。但是 memoize()
每个装饰函数只被调用一次。因此每个装饰函数都有自己的 cache
.
2) 关于cache = obj.cache = {}
:
函数也是 Python 中的对象。正如您已经假设的那样,obj.cache = {}
将在包装函数上创建一个新属性。本地缓存对象和包装函数上的缓存属性将指向同一个字典。
这并不是说 cache
是一个全局变量 - 它在 memoize 函数中是局部变量,它是函数的一个属性。
如果您有装饰函数 f
,您可以在全局范围内访问 f.cache
,如果这就是全局变量的意思。
如果您重复调用修饰函数,它将始终访问特定于修饰函数的相同 cache
。
解决内部函数不蜂 "memoized"。
def outer():
# do not add the decorator here!
def inner():
return 5
if(not hasattr(outer, "inner")):
# the "@" decorator is only syntactical sugar,
# we can simply call the decorator function to wrap another function
outer.inner = memoize( inner )
outer.inner()
return outer.inner()
outer()
outer()