Python函数参数前的单星号(*)和双星号(**)的作用

问题

阅读源码时,发现*运算符和**运算符修饰在函数定义参数前,如下代码所示:

def foo(x, y, *args):
    pass

def bar(x, y, **kwargs):
    pass

星号运算符在基础数学运算中,*表示乘法运算符,**表示指数运算符。

看来*运算符、**运算符还有另有他用。

解答

*args表示传递给函数一系列的参数,专业术语称之为“可变参数列表”(Arbitrary Argument Lists),与Java的“…”类似:

>>> def foo(*args):
...     for a in args:
...         print(a)
...
>>> foo(1)
1
>>> foo(1,2,3)
1
2
3
>>>
>>> def concat(*args, sep="/"):
...     return sep.join(args)
... 
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'

*args将位置参数们(positional arguments)打包成元组处理。

另外,函数定义参数前有**双星运算符修饰,它表示将关键词参数(keyword arguments)打包成字典处理:

>>> def bar(**kwargs):
...     for a in kwargs:
...        print(a, kwargs[a])  
... 
>>> bar(name='one', age=27)
name one
age 27

*运算符和**运算符可混合使用,但*修饰的参数必须在**修饰的参数的前面位置:

>>> def cheeseshop(kind, *arguments, **keywords):
...     print("-- Do you have any", kind, "?")
...     print("-- I'm sorry, we're all out of", kind)
...     for arg in arguments:
...         print(arg)
...     print("-" * 40)
...     for kw in keywords:
...         print(kw, ":", keywords[kw])
... 
>>> cheeseshop("Limburger", "It's very runny, sir.",
...            "It's really very, VERY runny, sir.",
...            shopkeeper="Michael Palin",
...            client="John Cleese",
...            sketch="Cheese Shop Sketch")
... 
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch

最后,*运算符另有它用。上文介绍了*args将位置参数们打包成元组处理,*运算符也可以起反作用,也就是将列表或元组解压成对应位置参数,专业术语称之为“解包参数列表”(Unpacking Argument Lists):

>>> list(range(3, 6))            # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))            # call with arguments unpacked from a list
[3, 4, 5]

类似的,**可以将字典解压成关键词参数:

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print("-- This parrot wouldn't", action, end=' ')
...     print("if you put", voltage, "volts through it.", end=' ')
...     print("E's", state, "!")

>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

参考

  1. Arbitrary Argument Lists - Python 3 doc
  2. Keyword Arguments - Python 3 doc
  3. Unpacking Argument Lists - Python 3 doc
  4. python - What does ** (double star/asterisk) and * (star/asterisk) do for parameters? - Stack Overflow
  5. Python - Star or Asterisk operator ( * ) - GeeksforGeeks

你可能感兴趣的:(Python,python,星号运算符)