核心要点
理解 * 解包序列、** 解包映射
函数定义中收集多余位置/关键字参数
能用于转发参数(wrapper 装饰器)
简要回答
*args 把多余位置参数收成 tuple,**kwargs 把多余关键字参数收成 dict;调用时 * 和 ** 可解包序列/字典传参。
标准回答
一、定义时收集
示例代码可以这样理解:
def f(a, *args, **kwargs):
# args: (2, 3)
# kwargs: {'x': 1}
f(1, 2, 3, x=1)
二、调用时解包
示例代码可以这样理解:
params = [1, 2]
opts = {'lr': 0.01}
optimizer.step(*params, **opts)
三、典型用途
- 装饰器 wrapper 转发任意签名:
def wrapper(*args, **kwargs): return fn(*args, **kwargs) - API 封装兼容未来参数
- 继承时调用
super().__init__(*args, **kwargs)
面试里可以把 **Python 中 *args 和 kwargs 是什 讲成“使用场景 + 常见坑 + 小例子”。尤其是 Python/工程基础题,面试官通常想看你是否知道真实代码里怎么避免可变对象、异常处理或可维护性问题。
四、仅 keyword 参数
def f(a, *, b, c=1): 中 b、c 必须按名传递。
回答思路
【定义】用一句话说清「Python 中 *args 和 **kwargs」
【原理】讲清关键机制或步骤(2~3 点)
【例子】举一个真实项目、论文或产品中的例子
【对比】与易混淆概念或替代方案比较(如有)
【收尾】总结适用场景 + 一个局限或风险
常见误区
⚠️ 常见踩坑
误区一:容易答偏的地方:只罗列名词、不会举例;混淆相似概念;忽略工程约束(成本、延迟、数据质量)。不确定时应主动说明假设。
追问
追问 1:* 单独作为参数是什么意思?
* 后的参数强制 keyword-only,如 def f(a, *, b) 必须 f(1, b=2) 不能 f(1, 2)。PEP 3102,提升 API 清晰性。
追问 2:解包时 dict 的键有什么要求?
**d 要求键为 str(Python 3),且对应函数存在的参数名。多余键会 TypeError 除非有 **kwargs 接收。
追问 3:args 和 kwargs 是固定名字吗?
不是,只有前导 */** 有语法意义。写成 def f(*pieces, **options) 完全可以,但惯例用 args/kwargs 便于阅读。
🔗 相似问题
同一考点的不同问法,换着练更稳
延伸学习
按主题分类的相关资源,便于系统复习
