星号 * 在 Python 中是啥意思? [复制]

Posted

技术标签:

【中文标题】星号 * 在 Python 中是啥意思? [复制]【英文标题】:What does asterisk * mean in Python? [duplicate]星号 * 在 Python 中是什么意思? [复制] 【发布时间】:2010-09-28 21:09:37 【问题描述】:

* 在 Python 中是否像在 C 中一样具有特殊含义?我在 Python Cookbook 中看到了这样的函数:

def get(self, *a, **kw)

请您向我解释一下或指出我在哪里可以找到答案(Google 将 * 解释为通配符,因此我找不到满意的答案)。

【问题讨论】:

另请参阅***.com/questions/14301967/… 以获取裸星号 这还是重复的吗?引用的问题专门关于函数的参数,而这个问题(至少从它的标题来看)也将涵盖像 [*my_dict] 这样的语法 【参考方案1】:

请参阅语言参考中的Function Definitions。

如果*identifier 的形式是 现在,它被初始化为一个元组 接收任何多余的位置 参数,默认为空 元组。如果**identifier 的形式是 目前,它被初始化为一个新的 字典接收任何多余的 关键字参数,默认为新的 空字典。

另外,请参阅Function Calls。

假设你知道位置参数和关键字参数是什么,这里有一些例子:

示例 1:

# Excess keyword argument (python 2) example:
def foo(a, b, c, **args):
    print "a = %s" % (a,)
    print "b = %s" % (b,)
    print "c = %s" % (c,)
    print args

foo(a="testa", d="excess", c="testc", b="testb", k="another_excess")

正如你在上面的例子中看到的,我们在foo函数的签名中只有参数a, b, c。由于dk 不存在,它们被放入 args 字典中。程序的输出是:

a = testa
b = testb
c = testc
'k': 'another_excess', 'd': 'excess'

示例 2:

# Excess positional argument (python 2) example:
def foo(a, b, c, *args):
    print "a = %s" % (a,)
    print "b = %s" % (b,)
    print "c = %s" % (c,)
    print args

foo("testa", "testb", "testc", "excess", "another_excess")

这里,由于我们正在测试位置参数,多余的必须放在最后,*args 将它们打包成一个元组,所以这个程序的输出是:

a = testa
b = testb
c = testc
('excess', 'another_excess')

您还可以将字典或元组解包到函数的参数中:

def foo(a,b,c,**args):
    print "a=%s" % (a,)
    print "b=%s" % (b,)
    print "c=%s" % (c,)
    print "args=%s" % (args,)

argdict = dict(a="testa", b="testb", c="testc", excessarg="string")
foo(**argdict)

打印:

a=testa
b=testb
c=testc
args='excessarg': 'string'

def foo(a,b,c,*args):
    print "a=%s" % (a,)
    print "b=%s" % (b,)
    print "c=%s" % (c,)
    print "args=%s" % (args,)

argtuple = ("testa","testb","testc","excess")
foo(*argtuple)

打印:

a=testa
b=testb
c=testc
args=('excess',)

【讨论】:

虽然这是一个非常精确的定义,但却是一个非常糟糕的解释;并且极不可能真正帮助苦苦挣扎的程序员 文档链接已损坏。 没有参数名时星号是什么意思?例如在pprint类的一些函数中。 它将常规参数与仅关键字参数分开。来自 '*' 的文档索引页面:docs.python.org/dev/reference/compound_stmts.html#index-22 我觉得这个解释很有启发性。评论者明确表示“假设一个人知道位置和关键字参数是什么。”所以他做得非常好。从所有标准来看,这都是很好的解释【参考方案2】:

我只有一件事要补充,其他答案中并不清楚(为了完整起见)。

您也可以在调用函数时使用星号。例如,假设您有这样的代码:

>>> def foo(*args):
...     print(args)
...
>>> l = [1,2,3,4,5]

您可以像这样将列表 l 传递给 foo...

>>> foo(*l)
(1, 2, 3, 4, 5)

你可以对字典做同样的事情...

>>> def foo(**argd):
...     print(argd)
...
>>> d = 'a' : 'b', 'c' : 'd'
>>> foo(**d)
'a': 'b', 'c': 'd'

【讨论】:

很抱歉在 7 年后提出这个问题,但是如果你从 fn 声明中删除 ** 只保留 def foo(argd): 并运行 foo(d) 你会得到相同的结果。那为什么要使用** @David 是的,你是对的。这个例子只是为了演示如何“解包”一个字典,然后在函数中“重新打包”它。例如,foo(a="b", c="d") 也会提供与foo(**d) 相同的输出。 我看到了第一个答案,我想,“不,这不是我想要的”,然后我看到了你的答案:) 为清楚起见,此示例使用* 解压缩序列(例如列表),并将其作为参数传递给使用*args 任意数量的位置参数的函数。 【参考方案3】:

以上所有答案都非常清楚和完整,但为了记录,我想确认 python 中 * 和 ** 的含义与 C 中看起来相似的运算符的含义绝对没有相似之处。

它们被称为参数解包和关键字参数解包运算符。

【讨论】:

有必要澄清一下,我最初的想法是通过引用传递 *【参考方案4】:

单星表示变量“a”将是提供给函数的额外参数的元组。双星表示变量“kw”将是一个可变大小的字典,其中包含随关键字提供的额外参数。

尽管实际行为已明确,但有时仍可能非常不直观。编写一些示例函数并使用各种参数样式调用它们可能会帮助您了解允许的内容和结果。

def f0(a)
def f1(*a)
def f2(**a)
def f3(*a, **b)
etc...

【讨论】:

不要吹毛求疵,但如果您使用单星,则参数将存储为元组,而不是列表。【参考方案5】:

我发现 * 在编写将另一个回调函数作为参数的函数时很有用:

def some_function(parm1, parm2, callback, *callback_args):
    a = 1
    b = 2
    ...
    callback(a, b, *callback_args)
    ...

这样,调用者可以传入任意额外参数,这些参数将传递给他们的回调函数。好处是回调函数可以使用普通的函数参数。也就是说,它根本不需要使用 * 语法。这是一个例子:

def my_callback_function(a, b, x, y, z):
    ...

x = 5
y = 6
z = 7

some_function('parm1', 'parm2', my_callback_function, x, y, z)

当然,闭包提供了另一种方法来做同样的事情,而不需要您通过 some_function() 和 my_callback_function() 传递 x、y 和 z。

【讨论】:

以上是关于星号 * 在 Python 中是啥意思? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

“**”在python中是啥意思? [复制]

以下代码中的 zip(*res) 在 python 中是啥意思? [复制]

__init__(self) 在 Python 中是啥意思? [复制]

Ruby 中的 *(星号)是啥意思? [复制]

这个符号在 C++ 中是啥意思? [复制]

这个f在这句话中是啥意思? [复制]