“关键字参数”与常规参数有何不同?不能将所有参数都传递为name=value
而不是使用位置语法吗?
10 回答
有两个相关的概念,都称为“关键字参数”。
在调用方,也就是其他评论者提到的,您可以按名称指定一些函数参数。您必须在所有没有名称的参数(位置参数)之后提及它们,并且任何未提及的参数都必须有默认值。
另一个概念是在函数定义方面:您可以定义一个按名称获取参数的函数——您甚至不必指定这些名称是什么。这些是纯关键字参数,不能按位置传递。语法是
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)
有两种方法可以将参数值分配给函数参数,这两种方法都可以使用。
按位置。位置参数没有关键字并且首先分配。
按关键字。关键字参数具有关键字,并在位置参数之后分配第二个。
请注意,您可以选择使用位置参数。
如果你不使用位置参数,那么——是的——你写的所有东西都会变成一个关键字参数。
当你调用一个函数时,你决定使用位置或关键字或混合。如果需要,您可以选择执行所有关键字。我们中的一些人不会做出这种选择并使用位置参数。
令我惊讶的是,似乎没有人指出可以传递满足形式参数的键控参数参数字典,就像这样。
>>> 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
>>>
使用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'`
这在您有许多相似的参数彼此相邻的情况下会有所帮助,特别是如果它们属于同一类型,在这种情况下,我更喜欢使用命名参数,或者如果参数属于一起,我会创建一个自定义类。
我很惊讶没有人提到你可以混合使用位置和关键字参数来做这样的偷偷摸摸的事情,使用*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])
这允许您使用可能具有您不想预先定义的键的任意关键字参数。
我正在寻找一个使用类型注释具有默认 kwargs 的示例:
def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
return ' '.join([a, b, c, str(kwargs)])
例子:
>>> print(test_var_kwarg('A', c='okay'))
A B okay {}
>>> d = {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', c='c', b='b', **d))
a b c {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', 'b', 'c'))
a b c {}
只需补充/添加一种方法来定义调用函数时未在关键字中分配的参数的默认值:
def func(**keywargs):
if 'my_word' not in keywargs:
word = 'default_msg'
else:
word = keywargs['my_word']
return word
通过以下方式调用:
print(func())
print(func(my_word='love'))
你会得到:
default_msg
love
阅读有关python 的更多信息:*args
https ://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3**kwargs