我不确定它是否可能,我想将字典解压缩到函数中,但我没有类似的参数。是否可以轻松地将字典限制为子集?
def foo(a=0, b=0, c=0):
print("a=%s, b=%s, c=%s"%(a,b,c))
my_dict = {'a':10, 'b':20, 'd':40}
foo(**my_dict)
输出
TypeError Traceback (most recent call last)
<ipython-input-1-d40731664736> in <module>()
3
4 my_dict = {'a':10, 'b':20, 'd':40}
----> 5 foo(**my_dict)
TypeError: foo() got an unexpected keyword argument 'd'
我想获得
a=10, b=20, c=0
结果“d”被自动拒绝。
这只是一个例子。在我的情况下,函数不是我的,我无法重新定义她的参数,foo是不可修改的。
我在foo()的情况下有许多函数,这些函数是对象的方法。
有什么想法吗?
答案 0 :(得分:4)
Inspecting the function signature会有所帮助:
import inspect
params = inspect.signature(foo).parameters.keys()
foo(**{k: v for k, v in my_dict.items() if k in params})
答案 1 :(得分:2)
这是使用inspect
的(希望)正确的解决方案。由于inspect
返回的参数列表可能包含星形参数和仅位置参数,因此仅仅比较名称是不够的。
import inspect
def filter_kwds(f, kwds):
params = inspect.signature(f).parameters
if any(p.kind == inspect.Parameter.VAR_KEYWORD for p in params.values()):
return kwds
else:
return {k:kwds[k] for k, v in params.items()
if k in kwds and v.kind in (inspect.Parameter.KEYWORD_ONLY,
inspect.Parameter.POSITIONAL_OR_KEYWORD)}
def f(a, *b, c=4):
pass
def g(a, *b, c=4, **d):
pass
print(filter_kwds(f, dict(a=1, b=2, d=4)))
print(filter_kwds(g, dict(a=1, b=2, d=4)))
输出:
{'a': 1}
{'a': 1, 'b': 2, 'd': 4}
请注意,第一个示例中的函数省略了星形arg的名称,在第二个示例中检测到存在双星arg,因此不进行过滤