对GetData1的调用运行良好并打印:
hello 67 8.3
对GetData2的调用失败:
TypeError: __call__() got an unexpected keyword argument 'arg1'
我的代码是
class Memoized(object):
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args):
print args
with Locker:
try:
return self.cache[args]
except KeyError:
self.cache[args] = value = self.func(*args)
return value
def GetData1(arg1, arg2, arg3) :
print arg1, arg2, arg3
@Memoized
def GetData2(arg1, arg2, arg3) :
print arg1, arg2, arg3
r = { 'arg1' : 'hello', 'arg2': 67, 'arg3' : 8.3 }
GetData1(**r)
GetData2(**r)
答案 0 :(得分:3)
您的@Memoized
类替换(包装)GetData2()
函数并将其自身隐藏,是一个可调用的*args
,但没有**kwargs
。
可能的解决方案可能是
def __call__(self, *args, **kwargs):
print args
with Locker:
kwitems = tuple(sorted(kwargs.items()))
try:
return self.cache[args, kwitems]
except KeyError:
self.cache[args, kwitems] = value = self.func(*args)
return value
但是如果用
调用它,它会对缓存产生影响GetData2(1, 2, 3)
或
GetData2(arg1=1, arg2=2, arg3=3)
或任何其他组合。
呼叫路径为:
wrapped GetData2()
--> Memoized.__call__()
--> self.func()
--> original GetData2()
答案 1 :(得分:0)
至少将参数传递给__call__()
会有问题。尝试将*args
- 函数中的__call()__
更改为**args
。这意味着您不会传递参数的任意元组,而是将关键字参数作为字典传递。
class Memoized(object):
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, **args):
print args
....
这将导致类似这样的事情:
In [16]: GetData2(**r)
{'arg1': 'hello', 'arg2': 67, 'arg3': 8.3}
但是,这可能会改变您期望缓存例程的工作方式。