在 Python 中有很多地方可以看到*和**。在某些情形下,无论是对于新手程序员,还是从其他很多没有完全相同操作符的编程语言迁移过来的人来说,这两个操作符都可能有点神秘。因此,我想讨论一下这些操作符的本质及其使用方式。
多年以来,*和**操作符的功能不断增强。在本文中,我将讨论目前这些操作符所有的使用方法,并指出哪些使用方法只能在目前的 Python 版本中应用。因此,如果你学习过 Python 2 中*和**的使用方法,那么我建议你至少浏览一下本文,因为 Python 3 中添加了许多*和**的新用途。
如果你是新接触 Python 不久,还不熟悉关键字参数(亦称为命名参数),我建议你首先阅读我有关Python中的关键字参数的文章。
不属于我们讨论范围的内容
在本文中, 当我讨论*和**时,我指的是*和**前缀操作符,而不是中缀操作符。
也就是说,我讲述的不是乘法和指数运算:
那么我们在讨论什么内容呢?
我们讨论的是*和**前缀运算符,即在变量前使用的*和**运算符。例如:
上述代码中展示了*的两种用法,没有展示**的用法。
这其中包括:
使用*和**向函数传递参数
使用*和**捕获被传递到函数中的参数
使用*接受只包含关键字的参数
使用*在元组解包时捕获项
使用*将迭代项解压到列表/元组中
使用**将字典解压到其他字典中
即使你认为自己已经熟悉*和**的所有使用方法,我还是建议你查看下面的每个代码块,以确保都是你熟悉的内容。在过去的几年里,Python 核心开发人员不断地为这些操作符添加新的功能,对于使用者来说很容易忽略*和**‘的一些新用法。
星号用于将可迭代对象拆分并分别作为函数参数
当调用函数时,*运算符可用于将一个迭代项解压缩到函数调用中的参数中:
print(*fruits)代码行将fruits列表中的所有项作为独立的参数传递给print函数调用,甚至不需要我们知道列表中有多少个参数。
*运算符在这里远不止是语法糖而已。要想用一个特定的迭代器将所有项作为独立的参数传输,若不使用*是不可能做到的,除非列表的长度是固定的。
下面是另一个例子: