def accept(**kwargs):
pass
如果我定义了accept
,我希望通过传递一个dict的参数来调用它。所有dict参数都需要星号吗?
如果我做以下事情怎么办?
def accept(dict):
pass
dict = {...}
accept(dict)
具体来说,我想为类实现一个update
方法,它将dict保存为容器。就像dict.update方法一样,它将dict作为参数并修改容器的内容。在这种具体情况下我应该使用kwargs吗?
答案 0 :(得分:2)
**
将所有关键字参数收集为字典。
>>> def accept(**kwargs): # isinstance(kwargs, dict) == True
... pass
...
使用关键字参数调用:
>>> accept(a=1, b=2)
使用**
运营商致电:
>>> d = {'a': 1, 'b': 2}
>>> accept(**d)
>>> accept(d)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: accept() takes exactly 0 arguments (1 given)
请参阅Python tutorial - Keyword argument和Unpacking Argument Lists。
答案 1 :(得分:1)
请参阅下面的f
。函数f
有两个参数,一个名为name
的位置参数和一个关键字参数message
。它们是函数调用框架中的局部变量。
当您执行f("John", **{"foo": "123", "message": "Hello World"})
时,函数f
将解压缩字典到其本地变量的键/值对。最后,您有三个本地变量:name
,foo=123
和message=Hello World
。
**kwargs
,双星号的目的是用于未知的关键字参数。
对比这个:
def f(name, message=None):
if message:
return name + message
return name
我在告诉用户您是否想要拨打f
,您可以传递关键字参数message
。这是我唯一能接受并希望收到的kwarg,如果有这样的话。如果您尝试f("John", foo="Hello world")
,您将获得意外的关键字参数。
**kwargs
非常有用,然后您可以使用它。
def f(name, message=None, **kwargs):
if message:
return name + message
return name
在第二个示例中,您可以在省略f("John", **{"foo": "Hello Foo"})
的同时执行message
。您也可以f("John", **{"foo": "Hello Foo", "message": "Hello Message"})
。
如你所见,你可以忽略它。这里f("John", **{"foo": "Hello Foo", "message": "Hello Message"})
我仍然只使用message
而忽略其他所有内容。
除非您需要不注意输入,否则请勿使用**kwargs
。
如果你的函数只需要字典并修改字典,不使用个别密钥,那么只需传递字典即可。没有理由将字典项目变成变量。
但这是**kwargs
的两个主要用法。
假设我有一个类,我想动态创建属性。我可以使用setattr
从输入中设置类属性。
class Foo(object):
def __init__(**kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
如果我Foo(**{"a": 1, "b": 2})
,我会在最后得到Foo.a
和Foo.b
。
当您必须处理遗留代码时,这尤其有用。但是,存在很大的安全问题。想象一下,你拥有一个MongoDB实例,这是一个用于写入数据库的容器。想象一下,这个dict是来自用户的请求表单对象。用户可以铲任何东西,你只需将它保存在数据库中就可以了吗?这是一个安全漏洞。确保验证(使用循环)。
kwargs的第二个常见用法是你不知道我已经涵盖的事情(它实际上是第一种常见用法)。
答案 2 :(得分:1)
如果要将字典作为输入传递给函数,可以像这样执行
def my_function1(input_dict):
print input_dict
d = {"Month": 1, "Year": 2}
my_function1(d) # {'Month': 1, 'Year': 2}
这是直截了当的。让我们看看**kwargs
方法。 kwargs
代表关键字参数。因此,您需要将参数实际传递为键值对,如此
def my_function2(**kwargs):
print kwargs
my_function2(Month = 1, Year = 2)
但是如果你有一本字典,如果你想将它作为参数传递给my_function2
,可以通过解包来完成,就像这样
my_function2(**d)