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中,星号操作符 * 可以用于多种场景,其主要的作用是将可迭代对象拆分成个的元素。 1.传递参数: 首先,* 可以用于将一个可迭代对象(如列表或字符串)作为函数的参数传递到另一个函数中,这种操作方式通常用于参数不固定的函数。 示例: ``` def add(*args): return sum(args) print(add(1,2,3)) # 输出6 ``` 2.拆分序列: * 还可以用于解包(或拆分)序列类型的数据结构,如列表、元组等,使其变成个的元素。 示例: ``` num_list = [1, 2, 3, 4] print(*num_list) # 输出1 2 3 4 ``` 3.拼接多个列表: 将多个列表拼接为一个大列表时,也可以使用 * 操作符。 示例: ``` list1 = [1, 2, 3] list2 = [4, 5, 6] list3 = [7, 8, 9] new_list = [*list1, *list2, *list3] print(new_list) # 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9] ``` 双星操作符 ** : 双星操作符 ** 主要用于将字典类型的数据解包(或展开)成关键字参数,这种操作方式通常用于函数或方法的调用。 示例: ``` def add(a,b,c): return a+b+c dict1 = {'a':1,'b':2,'c':3} print(add(**dict1)) # 输出6 ``` 总结: 星号操作符 * 和双星操作符 ** 在Python中使用非常广泛,掌握它们的使用方式可以大大提高程序开发的效率。我们在函数或方法中经常会看到这两个操作符,只要学会它们的使用方法,就可以轻松地处理函数的参数和返回值,同时也可以方便地操作数据结构中的元素。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值