**(双星/星号)和 *(星号/星号)在函数调用中意味着什么?
在 zip(*x)
或 f(**k)
等代码中,*
和 **
的作用是什么> 分别是什么意思? Python 如何实现该行为,以及对性能有何影响?
另请参阅:将元组扩展为参数。请使用该问题来结束 OP 需要在参数上使用 *
并且不知道它存在的问题。同样,对于使用 **
的情况,请使用 Converting Python dict to kwargs?。
请参阅**(双星/星号)和*(星号/星号)对参数有什么作用?了解互补内容关于参数的问题。
In code like zip(*x)
or f(**k)
, what do the *
and **
respectively mean? How does Python implement that behaviour, and what are the performance implications?
See also: Expanding tuples into arguments. Please use that one to close questions where OP needs to use *
on an argument and doesn't know it exists. Similarly, use Converting Python dict to kwargs? for the case of using **
.
See What does ** (double star/asterisk) and * (star/asterisk) do for parameters? for the complementary question about parameters.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
单星号
*
将序列或集合解包为位置参数。假设我们使用
*
解包运算符,我们可以编写s = add(*values)
,这相当于编写s = add(1, 2 )
。双星
**
对字典做同样的事情,为命名参数提供值:两个运算符都可以用于同一个函数调用。例如,给定:
则
s = add(*values1, **values2)
相当于s = sum(1, 2, c=10, d=15)
。另请参阅 Python 中教程的相关部分文档。
同样,
*
和**
也可用于参数。使用*
允许函数接受任意数量的位置参数,这些参数将被收集到单个参数中:现在,当调用该函数时,如
s = add(1, 2, 3, 4 , 5)
,values
将是元组(1, 2, 3, 4, 5)
(当然,它会产生结果15)。
类似地,标有
**
的参数将接收一个dict
:这允许指定大量可选参数而无需声明它们。
同样,两者可以结合起来:
A single star
*
unpacks a sequence or collection into positional arguments. Suppose we haveUsing the
*
unpacking operator, we can writes = add(*values)
, which will be equivalent to writings = add(1, 2)
.The double star
**
does the same thing for a dictionary, providing values for named arguments:Both operators can be used for the same function call. For example, given:
then
s = add(*values1, **values2)
is equivalent tos = sum(1, 2, c=10, d=15)
.See also the relevant section of the tutorial in the Python documentation.
Similarly,
*
and**
can be used for parameters. Using*
allows a function to accept any number of positional arguments, which will be collected into a single parameter:Now when the function is called like
s = add(1, 2, 3, 4, 5)
,values
will be the tuple(1, 2, 3, 4, 5)
(which, of course, produces the result15
).Similarly, a parameter marked with
**
will receive adict
:this allows for specifying a large number of optional parameters without having to declare them.
Again, both can be combined:
在函数调用中,单星将列表转换为单独的参数(例如,给定
zip(*x)
与zip(x1, x2, x3)
相同>x=[x1,x2,x3]),双星将字典转换为单独的关键字参数(例如f(**k)
与f( x=my_x, y=my_y)
给定k = {'x':my_x, 'y':my_y}
在函数定义中,情况相反:单星。将任意数量的参数转换为列表,双开头将任意数量的关键字参数转换为字典,例如
def foo(*x)
表示“foo 接受任意数量的参数,并且它们。可以通过x
访问(即如果用户调用foo(1,2,3)
,x
将是(1, 2, 3)
)" 和def bar(**k)
表示“bar 接受任意数量的关键字参数,并且可以通过k
访问它们(即如果用户调用bar(x=42, y=23)
,k
将是{'x': 42, 'y': 23}< /代码>)”。
In a function call, the single star turns a list into separate arguments (e.g.
zip(*x)
is the same aszip(x1, x2, x3)
givenx=[x1,x2,x3]
) and the double star turns a dictionary into separate keyword arguments (e.g.f(**k)
is the same asf(x=my_x, y=my_y)
givenk = {'x':my_x, 'y':my_y}
.In a function definition, it's the other way around: the single star turns an arbitrary number of arguments into a list, and the double start turns an arbitrary number of keyword arguments into a dictionary. E.g.
def foo(*x)
means "foo takes an arbitrary number of arguments and they will be accessible throughx
(i.e. if the user callsfoo(1,2,3)
,x
will be(1, 2, 3)
)" anddef bar(**k)
means "bar takes an arbitrary number of keyword arguments and they will be accessible throughk
(i.e. if the user callsbar(x=42, y=23)
,k
will be{'x': 42, 'y': 23}
)".我发现这对于存储函数调用的参数特别有用。
例如,假设我对函数“add”进行了一些单元测试:
除了手动执行诸如
add(test[0], test[1])
之类的操作之外,没有其他方法可以调用 add ,这很丑。另外,如果变量的数量可变,那么代码可能会因为您需要的所有 if 语句而变得非常难看。另一个有用的地方是定义工厂对象(为您创建对象的对象)。
假设您有一些工厂类,它生成 Car 对象并返回它们。
您可以让
myFactory.make_car('red', 'bmw', '335ix')
创建Car('red', 'bmw', '335ix')
,然后返回它。当您想要调用超类的构造函数时,这也很有用。
I find this particularly useful for storing arguments for a function call.
For example, suppose I have some unit tests for a function 'add':
There is no other way to call add, other than manually doing something like
add(test[0], test[1])
, which is ugly. Also, if there are a variable number of variables, the code could get pretty ugly with all the if-statements you would need.Another place this is useful is for defining Factory objects (objects that create objects for you).
Suppose you have some class Factory, that makes Car objects and returns them.
You could make it so that
myFactory.make_car('red', 'bmw', '335ix')
createsCar('red', 'bmw', '335ix')
, then returns it.This is also useful when you want to call the constructor of a superclass.
它被称为扩展调用语法。来自文档:
和:
It is called the extended call syntax. From the documentation:
and:
当定义可能有许多具有相同值的键的字典时,它也很有用。例如,
可以写成,
It is also useful when defining a dictionary that may have many keys with the same value. For Example,
can be written,