当函数需接收数量不确定但类型一致的值时该用args,它将多余位置参数收为不可变tuple,必须位于普通参数之后、kwargs之前;示例:def sum_all(args): return sum(args)。

什么时候该用 *args 而不是普通参数?
当函数需要接收「数量不确定但类型一致」的值时,*args 是最直接的选择。比如做求和、拼接、批量处理——这些操作天然不预设参数个数。
-
*args把多余的位置参数收集成一个tuple,不可变,但遍历安全 - 它必须写在普通参数之后、
**kwargs之前,顺序错会报SyntaxError: invalid syntax - 不要试图在调用时写
<em>args=[1,2,3]</em>:那是解包动作,定义函数时只需args - 示例:
def sum_all(*args): return sum(args) # args 是 (1, 2, 3) 而不是 [1,2,3]
sum_all(1, 2, 3) # → 6 sum_all() # → 0(空 tuple 的 sum 是 0)
**kwargs 接收关键字参数的边界在哪?
**kwargs 捕获所有未被显式声明的关键字参数,存为 dict。它适合配置类、装饰器、转发调用等场景。
- 键名必须是合法标识符,否则调用时会报
TypeError: function() got an unexpected keyword argument '123' - 如果函数已有同名参数(如
def f(x, **kwargs)),传入f(x=1, x=2)会直接报错,Python 不允许重复绑定 -
*<em>kwargs</em>不能出现在args前面,语法上禁止 - 示例:
def log_event(**kwargs): print("Received:", kwargs)
log_event(user="alice", action="login", status=200)
→ Received: {'user': 'alice', 'action': 'login', 'status': 200}
混合使用 *args 和 **kwargs 时最容易漏掉什么?
三者共存时的合法顺序只能是:def f(a, b, *args, c=10, *<em>kwargs)</em>。中间那个 c=10 是 keyword-only 参数,它必须靠关键字传入,且位于 args 之后、**kwargs 之前。
- 忘记 keyword-only 参数的强制命名规则,会导致
TypeError: f() takes 2 positional arguments but 3 were given - 在函数内部误把
<strong>kwargs</strong>当成可变对象直接修改(如kwargs.pop('x')),其实它只是个普通 dict,没问题;但若想透传给下层函数,得记得加解包 - 常见错误写法:
next_func(kwargs)(传了 dict)→ 正确是next_func(**kwargs) - 参数顺序记混:Python 3.8+ 支持
/和<em></em>显式分隔,但日常编码中仍建议严格遵守positional → args → keyword-only → **kwargs链
实际项目里哪些地方非用它们不可?
硬编码固定参数个数会快速让接口僵化。真实场景中,*args 和 **kwargs 往往出现在:
- 装饰器的通用包装逻辑:
def timer(func): def wrapper(*args, **kwargs): ...,否则无法适配任意被装饰函数 - 类的
<strong>init</strong>中做参数预处理,再转交给父类:super().<strong>init</strong>(*args, **kwargs) - API 封装函数,把用户传来的任意字段透传给 requests:
requests.get(url, **req_kwargs) - 测试工具中模拟多变输入,比如断言多个返回值:
assert_equal(<em>expected_values, </em>actual_values)
真正难的不是语法,而是判断「这里到底该收,还是该透,还是该校验」——多数 bug 出在没检查 *<em>kwargs</em> 里有没有非法键,或没对 args 做长度/类型兜底。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











