一、序列和可迭代对象拆包
1. 调用函数时在参数前面加上一个*,利用拆包
divmod(20, 8) #输出:(2, 4)
t = (20, 8)
divmod(*t) #输出:(2, 4)
2. 使用*获取余下的项
定义函数时可以使用*args捕获余下的任意数量的参数,这是Python的一个经典特性。
a, b,*rest = range(5)
a, b, rest #输出: (0, 1, [2, 3, 4])
a, b,*rest = range(3)
a, b, rest #输出: (0, 1, [2])
a, b,*rest = range(2)
a, b, rest #输出: (0, 1, [])
并行赋值时,*前缀只能应用到一个变量上,不过可以是任何位置上的变量。
a, *body, c, d = range(5)
a, b, rest #输出: (0, [1, 2], 3, 4)
*head, b, c, d = range(5)
head, b, c, d #输出: ([0, 1], 2, 3, 4)
二、在函数调用和序列字面量中使用*拆包
1. 在函数调用中可以多次使用*
def fun(a, b, c, d, *rest):
return a, b, c, d, rest
fun(*[1, 2], 3, *range(4, 7)) #输出:(1, 2, 3, 4, (5, 6))
2. 定义列表、元组或集合字面量时,也可以使用*
*range(4), 4 #输出:(0, 1, 2, 3, 4)
[*range(4), 4] #输出:[0, 1, 2, 3, 4]
{*range(4), 4, *(5, 6, 7)} #输出:{0, 1, 2, 3, 4, 5, 6, 7}
3. 映射拆包
首先,调用函数时,不止一个参数可以使用**。但是,所有键都要是字符串,而且在所有参数中是唯一的(因为关键字参数不可重复)。
def dump(**kwargs):
return kwargs
dump(**{'x': 1}, 'y': 2, **{'z': 3}) #输出:{'x': 1, 'y': 2, 'z': 3}
其次,**可在dict字面量中使用,同样可以多次使用。
{'a': 0,**{'x': 1}, 'y': 2, **{'z': 3, 'x': 4}} #输出:{'a':0, 'x': 4, 'y': 2, 'z': 3}
三、强制关键字参数
在函数定义中,单独使用 * 可以强制后续参数必须通过关键字传入。
def greet(name, *, message="Hello"):
print(f"{message}, {name}!")
greet("Alice") # 输出 "Hello, Alice!"
greet("Bob", message="Hi") # 正确,输出 "Hi, Bob!"
greet("Charlie", "Hey") # 报错:位置参数不允许
四、match/case语句中使用“*_”
*_ 匹配任意数量的项,而且不绑定变量。
match record:
'''
匹配任何以字符串开头,
以嵌套两个浮点数的序列结尾的序列。
'''
case [str(name), *_, (float(lat), float(lon))]:
pass
总结
| 场景 | 示例 | 说明 |
|---|---|---|
| 乘法/重复 | 3 * 4 或 [1,2] * 3 | 数值乘法或序列重复 |
| 函数参数(*args) | def func(*args): … | 接收任意位置参数 |
| 解包参数 | func(*[1,2,3]) | 将列表解包为位置参数 |
| 强制关键字参数 | def func(a, *, b): … | b 必须通过关键字传入 |
| 扩展解包 | a, *b = [1,2,3] | 将剩余元素赋值给 b(列表) |
| 通配符导入 | from math import * | 导入模块所有公共名称 |
| 映射拆包 | def dump(**kwargs): dump(**{‘x’: 1}, ‘y’: 2, **{‘z’: 3}) | **可在dict字面量中使用,同样可以多次使用。 |
| match/case语句中使用 *_ | case [str(name), *_, (float(lat), float(lon))]: | 匹配任何以字符串开头,以嵌套两个浮点数的序列结尾的序列。 |
根据具体场景选择合适用法,注意避免滥用通配符导入和过度依赖可变参数以提高代码可读性
特殊用法&spm=1001.2101.3001.5002&articleId=147278461&d=1&t=3&u=e6b3282807f84aba8b67a81d4b3c3a9e)
1175

被折叠的 条评论
为什么被折叠?



