我已经实现了一个memoize
装饰器,它允许缓存一个函数。缓存键包括函数参数。类似地,cached
装饰器缓存了一个函数,但忽略了参数。这是代码:
class ApplicationCache (Memcached):
make_key
方法:UltraJSON快速传递一个字符串,该字符串SHA512散列成一个清晰的十六进制摘要:
def make_key (self, *args, **kwargs):
kwargs.update (dict (enumerate (args)))
string = ujson.encode (sorted (kwargs.items ()))
hashed = hashlib.sha512 (string)
return hashed.hexdigest ()
装饰器:由于memoize
Python 2.x 吸收了完全限定的函数名,我只是强制用户提供一个合理的name
:
def memoize (self, name, timeout=None):
assert name
def decorator (fn):
@functools.wraps (fn)
def decorated (*args, **kwargs):
key = self.make_key (name, *args, **kwargs)
cached = self.get (key)
if cached is None:
cached = fn (*args, **kwargs)
self.set (key, cached, timeout=timeout)
return cached
return decorated
return decorator
装饰者:它几乎是一个忽略参数的例外的cached
逐字副本:memoize
make_key
def cached (self, name, timeout=None):
assert name
def decorator (fn):
@functools.wraps (fn)
def decorated (*args, **kwargs):
key = self.make_key (name) ## no args!
cached = self.get (key)
if cached is None:
cached = fn (*args, **kwargs)
self.set (key, cached, timeout=timeout)
return cached
return decorated
return decorator
现在,我的问题cached
是,它要求重构:它应该使用memoize
并且想法是消除fn
(使用functools.partial
可能?)的论点,例如:
def cached (self, name, timeout=None):
## Reuse the more general `memoize` to cache a function,
## but only based on its name (ignoring the arguments)
我实际上不确定我是否在这里过度使用 DRY 原则,以及是否可以重用,因为当前的实现仅cached
在构建密钥时忽略参数(但显然不是在调用修饰函数时)。