[英]Python memoized with **kwargs when calling a function doesn't seem to work
The call to GetData1 works well and prints: 对GetData1的调用运行良好并打印:
hello 67 8.3
the call to GetData2 fails: 对GetData2的调用失败:
TypeError: __call__() got an unexpected keyword argument 'arg1'
My code is 我的代码是
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)
Your @Memoized
class replaces (wraps) the GetData2()
function and shadows it with itself, being a callable which takes *args
, but no **kwargs
. 你的@Memoized
类替换(包装) GetData2()
函数并用它自己GetData2()
它,是一个可调用的,它带*args
但没有**kwargs
。
A possible solution could be 可能的解决方案是
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
But then it makes a difference for the cache if you call it with 但是如果你用它调用它会对缓存产生影响
GetData2(1, 2, 3)
or with 或者
GetData2(arg1=1, arg2=2, arg3=3)
or any other combination. 或任何其他组合。
The call path is: 通话路径是:
wrapped GetData2()
--> Memoized.__call__()
--> self.func()
--> original GetData2()
At the very least there's a problem in how you pass parameters to __call__()
. 至少在如何将参数传递给__call__()
。 Try changing the *args
in your __call()__
-function to **args
. 尝试将__call()__
-function中的*args
更改为**args
。 This means that instead of passing an arbitary tuple of arguments you'll pass keyword arguments as a dictionary. 这意味着您不会传递参数的任意元组,而是将关键字参数作为字典传递。
class Memoized(object):
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, **args):
print args
....
This will then result in something like this: 这将导致类似这样的事情:
In [16]: GetData2(**r)
{'arg1': 'hello', 'arg2': 67, 'arg3': 8.3}
However this might change the way you expect your caching routine to work. 但是,这可能会改变您期望缓存例程的工作方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.