Python正常参数与关键字参数

“关键字参数”与常规参数有什么不同? 不能所有的参数传递为name=value而不是使用位置语法?

有两个相关的概念,都被称为“关键字争论”。

在调用方面,这是其他评论者所提到的,您可以通过名称指定一些函数参数。 你必须在没有名字的所有参数(位置参数)之后提及它们,并且必须有任何没有提到的参数的默认值。

另一个概念是在函数定义方面:您可以定义一个函数,它可以通过名称来获取参数 – 而且您甚至不必指定这些名称是什么。 这些是纯粹的关键字参数,不能在位置上传递。 语法是

 def my_function(arg1, arg2, **kwargs) 

您传入此函数的任何关键字参数将被放入名为kwargs的字典中。 您可以在运行时检查此字典的键,如下所示:

 def my_function(**kwargs): print str(kwargs) my_function(a=12, b="abc") {'a': 12, 'b': 'abc'} 

区别是重要的还有最后一个语言特征。 考虑以下功能:

 def foo(*positional, **keywords): print "Positional:", positional print "Keywords:", keywords 

*positional参数将存储传递给foo()所有位置参数,不限制您可以提供的数量。

 >>> foo('one', 'two', 'three') Positional: ('one', 'two', 'three') Keywords: {} 

**keywords参数将存储任何关键字参数:

 >>> foo(a='one', b='two', c='three') Positional: () Keywords: {'a': 'one', 'c': 'three', 'b': 'two'} 

当然,你可以同时使用两者:

 >>> foo('one','two',c='three',d='four') Positional: ('one', 'two') Keywords: {'c': 'three', 'd': 'four'} 

这些功能很少使用,但偶尔它们非常有用,重要的是要知道哪些参数是位置或关键字。

使用关键字参数和普通参数是一样的,除了顺序无关紧要。 例如下面的两个函数调用是相同的:

 def foo(bar, baz): pass foo(1, 2) foo(baz=2, bar=1) 

正常的参数

他们之前没有关键字。 顺序很重要!

 func(1,2,3, "foo") 

关键字参数

他们在前面有关键字。 他们可以以任何顺序!

 func(foo="bar", baz=5, hello=123) func(baz=5, foo="bar", hello=123) 

你也应该知道,如果你使用默认的参数,而忽略插入关键字,那么顺序将是重要的!

 def func(foo=1, baz=2, hello=3): ... func("bar", 5, 123) 

有两种方法将参数值分配给函数参数,两者都被使用。

  1. 按位置。 位置参数没有关键字,并且先分配。

  2. 按关键字。 关键字参数具有关键字,并且在位置参数之后被分配第二。

请注意, 可以选择使用位置参数。

如果不使用位置参数,那么 – 是的 – 写的所有东西都是关键字参数。

调用一个函数时,你可以决定使用位置,关键字还是混合。 你可以选择做所有的关键字,如果你想。 我们有些人不做这个选择,并使用位置参数。

我感到惊讶的是,似乎没有人指出可以通过一个满足形式参数的键参数参数字典。

 >>> def func(a='a', b='b', c='c', **kwargs): ... print 'a:%s, b:%s, c:%s' % (a, b, c) ... >>> func() a:a, b:b, c:c >>> func(**{'a' : 'z', 'b':'q', 'c':'v'}) a:z, b:q, c:v >>> 

我很惊讶没有人提到这个事实,你可以混合使用位置和关键字的参数做这样的偷偷摸摸的事情使用*args**kwargs ( 从这个网站 ):

 def test_var_kwargs(farg, **kwargs): print "formal arg:", farg for key in kwargs: print "another keyword arg: %s: %s" % (key, kwargs[key]) 

这允许你使用任意的关键字参数,这些关键字参数可能有你不想预先定义的关键字。

使用Python 3,您可以同时拥有必需和非必需的关键字参数 :

可选 :(为'b'定义的默认值)

 def func1(a, *, b=42): ... func1(value_for_a) # b is optional and will default to 42 

必需 (没有为'b'定义的默认值):

 def func2(a, *, b): ... func2(value_for_a, b=21) # b is set to 21 by the function call func2(value_for_a) # ERROR: missing 1 required keyword-only argument: 'b'` 

这可以帮助你有许多相似的参数,尤其是在相同类型的情况下,在这种情况下,我更喜欢使用命名参数,或者如果参数属于一起,我创建一个自定义类。