解包时*必须在**之前,否则报SyntaxError;*生成位置参数,**生成关键字参数;混合使用须为f(*args,**kwargs);嵌套解包需注意展平逻辑,partial可预设参数并支持后续解包。

用 * 和 ** 解包序列与字典时,参数顺序不能乱
Python 函数调用时解包,本质是把容器里的元素“平铺”成独立参数。但位置参数必须在关键字参数之前,解包也得守这个规矩:* 解包的可迭代对象必须出现在 ** 解包的字典之前,否则报 SyntaxError: positional argument follows keyword argument。
-
*解包后生成的是位置参数,会按顺序填入函数定义中靠前的形参 -
**解包后生成的是关键字参数,只匹配函数签名中同名的形参 - 混合使用时,必须写成
f(*args, **kwargs),不能写成f(**kwargs, *args) - 如果函数定义用了仅限关键字参数(如
def f(a, *, b)),解包后的*args无法覆盖b,必须显式通过**kwargs或直接传b=...
函数定义里用 *args 和 **kwargs 接收任意参数,但别忘了类型校验
接收任意参数看似灵活,实际调用方传错类型或漏传关键字段时,错误会延迟到函数内部逻辑才暴露,调试成本高。尤其当封装第三方 API 调用或构建配置驱动函数时,光靠 *args/**kwargs 不够安全。
- 用
**kwargs接收配置项时,建议用kwargs.get('timeout', 30)设默认值,而非直接kwargs['timeout'] - 对关键必填参数,可用
if 'url' not in kwargs: raise ValueError("missing required kwarg: 'url'")主动拦截 - 若需强类型约束,配合
typing.Union或pydantic.BaseModel做结构化解析,比纯字典更可靠
嵌套解包常见陷阱:*list_of_tuples 不等于 zip(*list_of_tuples)
想把 [(1, 'a'), (2, 'b')] 拆成两个参数传给 zip(),容易误写成 zip(*data) —— 这确实可行;但若想反向把多组数据“压平”进一个函数,比如 print(*[1, 2], *[3, 4]),Python 允许,而 print(*[1, 2], *['x', 'y']) 也合法。真正容易出错的是嵌套层级没理清。
-
*[[1,2], [3,4]]解包结果是[1,2], [3,4](两个列表),不是1,2,3,4 - 要展平二维列表,得用
itertools.chain.from_iterable()或列表推导式:[x for row in data for x in row] - 调用
requests.post(url, json=body, **headers)时,若headers是{'Content-Type': 'application/json'},解包没问题;但若误传成[('Content-Type', 'application/json')],**会报TypeError: ** must be mapping
用 functools.partial 配合解包预设参数,比闭包更轻量
当需要多次调用同一函数、仅部分参数变化时,partial 比手写闭包或 lambda 更清晰,且天然支持后续解包。它返回的新函数仍能正常接收 *args 和 **kwargs,适合构建配置化工具链。
立即学习“Python免费学习笔记(深入)”;
from functools import partialdef upload_file(path, server, timeout=30, retries=3): print(f"Uploading {path} to {server}, timeout={timeout}")
预设 server,保留其他参数开放
aws_upload = partial(upload_file, server="s3://bucket") aws_upload("data.csv", timeout=60) # ✅ 等价于 upload_file("data.csv", "s3://bucket", timeout=60)
也能配合解包
options = {"timeout": 45, "retries": 1} aws_upload("config.json", **options) # ✅
注意:partial 预设的参数优先级高于后续调用时传入的同名参数(即后者不会覆盖前者),这点和普通函数调用规则一致;但如果预设了 timeout=30,又在调用时写 timeout=60,则以调用时的值为准。
解包本身不难,难的是在多层调用、配置传递、类型混合的场景下,保持参数流向清晰、错误反馈及时。越早明确哪些该解包、哪些该校验、哪些该冻结,后期维护时踩的坑就越少。










