正常参数与关键字参数

mk1*_*k12 271 python arguments keyword optional-parameters named-parameters

"关键字参数"与常规参数有何不同?不能传递所有参数name=value而不是使用位置语法?

Ian*_*and 327

有两个相关的概念,都称为"关键字参数".

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

另一个概念是在函数定义方面:您可以定义一个按名称获取参数的函数 - 您甚至不必指定这些名称是什么.这些是纯关键字参数,不能在位置上传递.语法是

def my_function(arg1, arg2, **kwargs)
Run Code Online (Sandbox Code Playgroud)

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

def my_function(**kwargs):
    print str(kwargs)

my_function(a=12, b="abc")

{'a': 12, 'b': 'abc'}
Run Code Online (Sandbox Code Playgroud)

  • 措辞不清楚:通常你在被呼叫方面谈论呼叫方面的参数. (33认同)
  • +1并接受:你是唯一一个谈论两种类型的位置+关键字参数的人,其他人都认为我在谈论第一个或第二个(但它们仍然是好帖子).谢谢! (5认同)
  • 参数名称是否必须为`kwargs`或我可以将其重命名为sth。像`options`(`def my_fuction(arg1,arg2,** options)`)? (2认同)
  • 该名称可以是任何名称,尽管 `kwargs` 是没有更合适名称时的惯例 (2认同)
  • 我认为这里解释的第二个概念在技术上称为任意关键字参数。 (2认同)

too*_*php 180

最后一种语言特征是区别很重要.考虑以下功能:

def foo(*positional, **keywords):
    print "Positional:", positional
    print "Keywords:", keywords
Run Code Online (Sandbox Code Playgroud)

*positional参数将存储所有传递给位置参数foo(),没有限制,你能有多少提供.

>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}
Run Code Online (Sandbox Code Playgroud)

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

>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}
Run Code Online (Sandbox Code Playgroud)

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

>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}
Run Code Online (Sandbox Code Playgroud)

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

  • 很好的答案!如果我们改变函数定义,如`def foo(arg1,*positional,**keywords):`,那么只需要在`*positional`和`**keywords`之前传递所需位置参数的注释.这里`arg1`是位置和必需的.请注意,答案中的位置意味着可选和可变数量的位置参数. (3认同)
  • 是的很好的答案。另一个注意事项:如果你调用你的函数`foo(bar=True)`,你可以使用`bar = Keywords.pop('bar')` 与`bar = keyword.pop('bar', None)` 相同的方法获取值. 对于默认值,使用`bar = keyword.pop('bar', False)` (2认同)

Eli*_*rey 98

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

def foo(bar, baz):
    pass

foo(1, 2)
foo(baz=2, bar=1)
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你.非常有用,我可以****指定关键字arg作为位置arg,**和**位置arg作为关键字arg. (3认同)
  • 注意:这对于仅位置参数是不可能的(在 Python 3.8 中接受的 PEP 570 中引入)。签名为“pow(x, y, z=None, /)”的“pow”具有仅位置参数(参数列表中的“/”表示所有前面的参数都是仅位置参数。通过此更改,“pow” (x=5, y=3)` 导致 `Traceback (most最近一次调用最后): File "<stdin>", line 1, in <module> TypeError: pow() gets no keywords argument`。请参阅 https:// www.python.org/dev/peps/pep-0570/ (3认同)

Unk*_*own 46

位置参数

他们之前没有关键字.订单很重要!

func(1,2,3, "foo")
Run Code Online (Sandbox Code Playgroud)

关键字参数

他们在前面有关键字.它们可以按任何顺序排列!

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

func(baz=5, foo="bar", hello=123)
Run Code Online (Sandbox Code Playgroud)

您还应该知道,如果您使用默认参数并忽略插入关键字,那么订单将很重要!

def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
Run Code Online (Sandbox Code Playgroud)

  • 恕我直言,第三个例子(默认参数)不清楚.我想你在谈论当一个或多个参数声明默认值时会发生什么,并且调用使用位置表示法,但是提供的数量少于声明的参数数量.但是,您的示例已声明3,并且在调用中为3,因此默认值完全没有效果!你打算省略第3个arg吗?例如`func("bar",5)`?然后说`hello`得到它的默认值`3`. (7认同)

S.L*_*ott 23

有两种方法可以将参数值分配给函数参数,两种方法都可以使用.

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

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

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

如果不使用位置参数,那么 - 是的 - 写的所有东西都是一个关键字参数.

调用函数时,您决定使用位置或关键字或混合.如果需要,您可以选择执行所有关键字.我们中的一些人没有做出这个选择并使用位置参数.


小智 23

我很惊讶,似乎没有人指出可以传递一个满足形式参数的键控参数字典,就像这样.

>>> 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
>>> 
Run Code Online (Sandbox Code Playgroud)

  • +1是一种有用的技术.你的观点会更清楚,没有`,**kwargs`.这将证明即使是具有固定#参数的简单函数def也可以提供字典.也就是说,它在定义中不需要任何花哨的东西.然后你可以在定义中添加第二个例子WITH**kwargs,并显示如何通过它获得字典中的EXTRA项. (11认同)
  • 上面的第四个形式参数 - **kwargs是必要的,如果你用一个包含除'a','b'和'c'之外的键的字典调用func. (3认同)

Chr*_*ssy 15

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

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

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

必需(没有为'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'`
Run Code Online (Sandbox Code Playgroud)

这可以帮助你有很多相似的参数紧挨着彼此,特别是在相同类型的情况下,在这种情况下,我更喜欢使用命名参数,或者我创建一个自定义类,如果参数属于一起.

  • *required*变体非常有用.它敦促按名称给出args而不提供默认值,这通常没有意义. (2认同)

Gab*_*ley 11

我很惊讶没有人提到你可以混合位置和关键字参数来做这样的偷偷摸摸的事情*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])
Run Code Online (Sandbox Code Playgroud)

这允许您使用任意关键字参数,这些参数可能包含您不希望预先定义的键.