你有没有遇到过这种场景:写了个加法函数,结果用户一会儿传两个数,一会儿传五个,一会儿又传十个?硬写成 add(a, b, c, d, e) 显然不现实,改来改去还容易漏参数。这时候,「函数参数可变个数」就派上用场了。
Python 里的 *args 和 **kwargs
Python 用 *args 接收任意多个位置参数,用 **kwargs 接收任意多个关键字参数。名字不是固定的(args 和 kwargs 是约定俗成),但星号不能少。
def print_all(*args, **kwargs):
print("位置参数:", args) # 元组
print("关键字参数:", kwargs) # 字典调用它试试:
print_all(1, 2, "hello", name="小王", age=28)
# 输出:
# 位置参数: (1, 2, 'hello')
# 关键字参数: {'name': '小王', 'age': 28}实际小例子:日志记录器
开发中常要打日志,但每次想记点额外信息(比如模块名、用户ID),又不想反复改函数签名。用可变参数就很灵活:
def log(msg, *tags, level="INFO", **extra):
tag_str = " [" + " ".join(str(t) for t in tags) + "]" if tags else ""
extra_str = " " + str(extra) if extra else ""
print(f"[{level}]{tag_str} {msg}{extra_str}")这样调用都行:
log("登录成功")
log("数据库查询", "user", "slow")
log("订单创建", level="WARN", order_id=1001, amount=99.5)其他语言也支持,只是写法不同
JavaScript 用 rest 参数:function sum(...nums) { return nums.reduce((a,b) => a+b, 0); }
C# 用 params 关键字:static int Max(params int[] numbers) { ... }
Java 用可变参数语法:public void log(String... messages) { ... }
核心思路都一样:把“不确定有几个”的参数,打包成一个容器(数组、元组、列表等),函数内部再按需处理。
下次再看到别人函数里带 * 或 ...,别慌——它不是bug,是留了道门,专等你多塞几个参数进去。