1

“**关键字形式的形式参数”的目的究竟是什么?我把它放在引号中,因为这就是它在文档中所指的,但我很难找到关于它的信息,并认为它可能有一个正式的术语。

据我了解,它允许用户执行类似的操作

def foo(**keywords):
   for i in keywords:
       print(i, ":", keywords[i])

foo(val1="1", val2="2", val3="3")

输出:

val1 : 1
val2 : 2
val3 : 3

这究竟有什么好处?为了便于理解,传递字典变量不是更好吗?

4

4 回答 4

2

如果使用字典,调用函数将如下所示:

myfunv({"key1": "value1", "key2": "value2"})

使用 **kwargs 这变成

myfunc(key1="value1", key2="value2")

许多人更喜欢后者。

当您将参数透明地传递给另一个函数或类时,此构造也非常有用。例如,我在继承 Tkinter 小部件时经常使用它。我想支持基类的所有选项,所以我这样编码:

class MyFrame(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        <more code here>

这使我可以支持所有相同的论点,而不必明确列出所有论点。

于 2012-04-12T19:13:16.843 回答
1

一种用途是当您想要转发参数时。例如:

def do_some_work(kwd1=None, kwd2=None, ...):
    ....

def intermediate_function(some_other_params, **kwargs):
    ...
    do_some_work(**kwargs)

def main():
    intermediate_function(some_other_params, kwd1=5, kwd2='foo')

这样,如果您将参数添加到do_some_work,则不必将其添加到定义intermediate_function和调用中do_some_work


另一个使用它的地方是 Django 的信号处理程序。当你写一个处理程序时,你把它写成表格

def handle_signal(sender, instance, **kwargs):

以便将来可以更改 API 以传递其他参数,而无需用户将参数添加到一堆不会使用它们的方法中。

于 2012-04-12T19:10:56.623 回答
0

使用此构造,调用者可以使用标准关键字参数。

于 2012-04-12T19:08:14.923 回答
0

从历史上看,参数传递是通过位置参数或关键字参数传递的。将复杂对象作为参数传递是一个相对较新的功能,人们更愿意将值作为参数传递

  1. 这很简单
  2. 可读性

现在扩展概念,在支持时传递变量位置和关键字参数会产生上述结构。

有趣的是,通过构造仍然可以传递字典,但是负责任的程序员不想要的意图变得不那么明显了。

于 2012-04-12T19:11:40.017 回答