我将如何编写这样的装饰器。我希望能够在调用装饰器时指定 max_hits 的值(或可选地将其省略)。
例如,所需的用途是
@memoize(max_hits=7)
def a(val):
print val
或者
@memoize
def a(val):
print val
(使用第一个示例会给出关于不正确参数的错误。)
装饰器:
class memoize:
"""A decorator to cache previosly seen function inputs.
usage:
@memoize
def some_func(..
"""
def __init__(self, function, max_hits=None):
self.max_hits = max_hits
self.function = function
self.memoized = {}
def __call__(self, *args, **kwargs):
key = (args,tuple(kwargs.items()))
try:
return self.memoized[key]
except KeyError:
self.memoized[key] = self.function(*args,**kwargs)
return self.memoized[key]
最佳答案
您必须使 memoize
成为一个函数,该函数接受一个可选参数 max_hits
并返回一个装饰器(即另一个将该函数作为第一个参数的可调用对象);在这种情况下,您可以使用以下两种语法:
@memoize()
def func(x):
[...]
@memoize(max_hits=7)
def func(x):
[...]
所以,可能是这样的:
def memoize(max_hits=None):
"""Returns a decorator to cache previosly seen function inputs.
usage:
@memoize()
def some_func(..
"""
class decorator:
def __init__(self, function):
self.max_hits = max_hits
self.function = function
self.memoized = {}
def __call__(self, *args, **kwargs):
key = (args,tuple(kwargs.items()))
try:
return self.memoized[key]
except KeyError:
self.memoized[key] = self.function(*args,**kwargs)
return self.memoized[key]
return decorator
请注意,
@memoize()
将起作用,但您最初想要的 @memoize
语法不起作用;在后一种情况下,您使用 @memoize
修饰的函数将作为第一个参数 ( memoize
) 传递给 max_hits
。如果要处理这种情况,可以按如下方式扩展 memoize
:def memoize(max_hits=None):
if callable(max_hits):
# For sake of readability...
func = max_hits
decorator = memoize(max_hits=None)
return decorator(func)
[...original implementation follows here...]
关于Python - 如何为基于类的装饰器指定可选参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6018403/