python中 * 和 ** 的用法

Published on
12

一、算术运算

* 表示乘法

2 * 5  # 输出 10

** 表示乘方

2 ** 5  # 输出 32

这是最基础的用法,与其他编程语言类似。


二、函数参数处理

1. 形参收集参数

*args:收集任意数量的位置参数为元组。
示例:

def func(*args):
    print(args)  # 输出元组,如 (1, 2, 3)
func(1, 2, 3)

**kwargs:收集任意数量的关键字参数为字典。
示例:

def func(**kwargs):
    print(kwargs)  # 输出字典,如 {'a': 1, 'b': 2}
func(a=1, b=2)

注意:*args 需在 **kwargs 之前定义。

2. 实参解包参数

* 解包序列:将列表/元组拆分为位置参数传递。

def func(a, b, c):
    print(a, b, c)
args = [1, 2, 3]
func(*args)  # 等同于 func(1, 2, 3)

** 解包字典:将字典拆分为关键字参数传递。

kwargs = {'a': 1, 'b': 2, 'c': 3}
func(**kwargs)  # 等同于 func(a=1, b=2, c=3)

这在动态传参时非常灵活。


三、序列解包与合并

1. 结构化解包

提取首尾元素,中间元素合并为列表

a, *b, c = [1, 2, 3, 4, 5]
# a=1, b=[2,3,4], c=5

适用于处理不定长序列的分段操作。

2. 列表/元组合并

合并多个序列

list1 = [1, 2]
list2 = [3, 4]
merged = [*list1, *list2]  # 输出 [1, 2, 3, 4]

四、字典操作

1. 字典合并

** 合并字典:公共键的值会被后续字典覆盖。

dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
merged = {**dict1, **dict2}  # 输出 {'a': 1, 'b': 3, 'c': 4}

类似 dict.update(),但生成新字典。


五、高级用法

1. 限制参数类型

仅关键字参数:通过 * 分隔符强制后续参数以关键字形式传递。

def func(a, *, b):
    print(a, b)
func(1, b=2)  # 正确
func(1, 2)    # 报错:缺少关键字参数 b

增强代码可读性和安全性。

2. 构造复杂数据结构

动态生成列表/字典

values = [*range(3), *'abc']  # 输出 [0, 1, 2, 'a', 'b', 'c']
user = {'id': 1, **{'name': 'Alice', 'age': 20}}  # 合并字典

六、注意事项

  1. 优先级与顺序
    • 函数定义时,*args 必须在 **kwargs 之前。
    • 解包时,* 用于可迭代对象,** 仅用于字典。
  2. 可读性
    • 避免过度使用 ***,尤其是复杂场景下需注释说明逻辑。
  3. 替代方案
    • 简单合并操作可优先使用 sum()|(Python 3.9+ 的字典合并运算符)。

通过灵活运用 ***,可以显著提升代码的简洁性和动态处理能力,但需注意场景适配与可维护性。


0