为不同函数分离**kwargs
假设有一个高级函数,它可以接收多个函数作为参数,那么这个函数怎么能把关键字参数传递给这些函数呢?
举个例子
def eat(food='eggs', how_much=1):
print(food * how_much)
def parrot_is(state='dead'):
print("This parrot is %s." % state)
def skit(*lines, **kwargs):
for line in lines:
line(**kwargs)
skit(eat, parrot_is) # eggs \n This parrot is dead.
skit(eat, parrot_is, food='spam', how_much=50, state='an ex-parrot') # error
state
不是 eat
函数的关键字参数,那这样一来,skit
是怎么只把和它调用的函数相关的关键字参数传递过去的呢?
3 个回答
-1
这个代码定义了一个叫做`sample`的函数,它有三个参数:`a`、`b`和`c`。其中,`c`是一个可选参数,默认值是0。
* -> 在参数前面是位置参数,在参数后面是关键字参数
下面是一些调用这个函数的例子:
sample(1,2,c=10)
这行代码调用了`sample`函数,给`a`传了1,给`b`传了2,给`c`传了10。
sample(a=1,b=2,c=1)
这行代码也可以正常工作,因为我们用关键字的方式给每个参数赋值。
sample(1,2,c)
这行代码会出错,提示“TypeError”,意思是`sample`函数只接受两个位置参数,但这里给了三个参数。
8
如果你在所有的定义里加上 **kwargs
,那么你就可以把所有的参数都传进去:
def eat(food='eggs', how_much=1, **kwargs):
print(food * how_much)
def parrot_is(state='dead', **kwargs):
print("This parrot is %s." % state)
def skit(*lines, **kwargs):
for line in lines:
line(**kwargs)
在 **kwargs
里,如果有一些参数不是明确指定的关键字参数,它们就会被留在 kwargs
里,而像 eat
这样的函数会忽略这些参数。
举个例子:
>>> skit(eat, parrot_is, food='spam', how_much=50, state='an ex-parrot')
spamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspam
This parrot is an ex-parrot.
16
你可以根据一个函数的 func_code.co_varnames
(在 Python 2 中)来筛选 kwargs
字典里的内容:
def skit(*lines, **kwargs):
for line in lines:
line(**{key: value for key, value in kwargs.iteritems()
if key in line.func_code.co_varnames})
在 Python 3 中,应该用 __code__
来代替 func_code
。所以这个函数会是:
def skit(*lines, **kwargs):
for line in lines:
line(**{key: value for key, value in kwargs.iteritems()
if key in line.__code__.co_varnames})
另外可以参考: 你能列出一个 Python 函数接收的关键字参数吗?