将值分配给函数参数时,Python遵循的过程是什么?
我一直在试图理解Python为函数参数赋值时所遵循的算法,它只是非常混乱。我想更好地理解算法,以便我可以真正知道将什么值分配给哪些参数以及何时分配。有位置参数,关键字参数,* args,* kwargs和仅关键字参数。这些全部如何分配以及按什么顺序分配?将值分配给函数参数时,Python遵循的过程是什么?
看看下面的代码片段为一个具体的例子:
def func(a, b, c):
print(a, b, c)
如果我拨打以下格式此功能,它会正常运行:如果我运行它
func(c=3, *(1, 2)) # prints 1 2 3
然而使用此,它提供了SyntaxError
:
func(c=3, 1, 2)
如何是次的两种形式电话不同?在第一次调用中,元组被解包成单独的参数。与转换成第二种形式不一样吗?如果这就是发生了什么,那么第二种形式也应该起作用,但事实并非如此。
那么这里究竟发生了什么?
它没有什么特别之处:它就是Python的工作原理。
Python禁止在命名参数后传递位置参数。就像你不能用之后的可选参数或之后的之后的关键字参数定义一个函数。然而,在调用一个函数时,更多的是在命名参数前使用位置参数,而对于函数定义来说,它实际上是一个“消除模糊性”的问题。但它的工作方式肯定有一些对称性。
你可以绕过这是你通过拆包观察,但它是有代价的:这是一个有点慢,因为额外的工作:
def func(a, b, c):
pass
%timeit func(c=3, *(1, 2))
# 810 ns ± 16.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit func(1, 2, c=3)
# 383 ns ± 1.47 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
这实际上是非常重要的是要记住:如果您尝试与您付费的Pythons语言进行对抗。
如果你有兴趣,它基本上作品就像如果你的函数只有*args
和**kwargs
作为参数。它收集*args
中的所有位置参数和**kwargs
中的所有命名参数,然后尝试将它们“绑定”到实际的函数参数。
在Python中,当使用参数调用函数时,它将按照在函数定义中定义的顺序将这些值分配给参数。
对于防爆:
def func(a, b, c):
print(a, b, c)
func(a=3, *(1, 2))
这将导致
TypeError: func() got multiple values for keyword argument 'a'
OR
def func(a, b, c):
print(a, b, c)
func(b=3, *(1, 2))
这将导致
TypeError: func() got multiple values for keyword argument 'b'
因此,在这种情况下,变量c被明确分配,其余参数从变长参数列表中分配。
来到这个问题的第二部分,Python允许你只后所有的值都passed.Following代码将正常工作,明确分配的数据参数
def func(a, b, c):
print(a, b, c)
func(3, 1,c=2))
但不func(3,b=1,2) or func(a=3,1,2)
你可以在这里找到更多的信息What does ** (double star/asterisk) and * (star/asterisk) do for parameters?
但*为什么*不是有效的语法?它可以只分配关键字参数,然后将其余的值分配给任何空白参数,就像我在示例中为第二个呼叫类型所做的那样。 –
因为这就是Pythons语言的语法。解包参数与传递位置参数不同。 – MSeifert
@AsadMoosvi我更新了答案。我认为原来的答案错过了这一点。感谢您的评论 :) – MSeifert