以下代码:
def f(a=1):
pass
kwargs = {}
kwargs['a'] = 1
kwargs['b'] = 2
f(**kwargs)
(正确)引发异常:
Traceback (most recent call last):
File "tt.py", line 8, in <module>
f(**kwargs)
TypeError: f() got an unexpected keyword argument 'b'
有没有办法,使用functools或其他方法来解决这个问题,并找出函数没有使用哪些参数,以便能够将它们传递给另一个函数?例如,我可能有另一个功能:
def g(a=None, b=None):
pass
我想打电话,例如。
g(**kwargs)
但我只希望传递b
,因为a
已在前一个功能中“用完”。
现在我知道这不是理想的编码,但有些情况下它可以派上用场,而且实际上很容易向用户解释,例如: “其他参数将传递给f,任何未传递给f的参数都将传递给g”。
答案 0 :(得分:5)
我有点惊讶你提出这个问题,并担心你正在做一些你可能会后悔的事。
您是否尝试使用相同的字典调用不同的方法,并提供所有参数组合?
如果是这样,则处理这种情况所需的复杂性不应该在被调用的方法中处理,而是在调用代码中处理,例如,通过将kwargs
定制到要调用的特定方法:
def f(a=1):
pass
call_tailored_args(f, kwargs)
辅助函数将实现如下:
import inspect
def tailored_args(f, kwargs):
relevant_args = {k: v in kwargs if k in inspect.getargspec(f).args}
f(**relevant_args)
答案 1 :(得分:4)
这是你的意思吗?
def g(**kwargs):
a=kwargs.pop('a',None)
b=kwargs.pop('b',None)
print(a,b)
def f(**kwargs):
a=kwargs.pop('a',None)
print(a)
g(**kwargs)
kwargs = {'a':1,'b':2}
f(**kwargs)
# 1
# (None, 2)
答案 2 :(得分:1)
您可以使用装饰器删除额外的kwargs键:
def remove_args(fx):
def wrap(**kwargs):
kwargs2 = copy.copy(kwargs)
ret = None
done = False
while not done:
try:
ret = fx(**kwargs2)
done = True
except TypeError, ex:
key = re.findall("\'(\w+)\'", ex.message)[0]
del kwargs2[key] # Remove offending key
# print "%s removing %s" % (fx.__name__, key)
return ret
return wrap
@remove_args
def f1(a=1):
return "f1-ret"
@remove_args
def f2(b=1):
return "f2-ret"
kwargs = {"a": 1, "b": 2, "c": 3}
print f1(**kwargs)
print f2(**kwargs)