一、核心概念与用法
简单来说,*args 用于接收任意数量的位置参数,**kwargs 用于接收任意数量的关键字参数。它们本质上是一种语法约定(名字可以改,但 * 和 ** 是核心),目的是让函数能处理不确定数量的参数。
1. *args:可变位置参数
- 作用:将传入的多个位置参数打包成一个元组 (tuple),函数内部可以像操作元组一样使用
args。 - 示例代码:
def print_args(*args):
# 打印args的类型(是元组)
print("args的类型:", type(args))
# 遍历输出所有位置参数
for index, value in enumerate(args):
print(f"第{index+1}个位置参数: {value}")
# 调用函数,传入任意数量的位置参数
print_args(10, "Python", [1,2,3], True)
print_args("单独一个参数") # 也可以只传1个,甚至不传
args的类型: <class 'tuple'>
第1个位置参数: 10
第2个位置参数: Python
第3个位置参数: [1,2,3]
第4个位置参数: True
args的类型: <class 'tuple'>
第1个位置参数: 单独一个参数
2. **kwargs:可变关键字参数
- 作用:将传入的多个关键字参数打包成一个字典 (dict),函数内部可以像操作字典一样使用
kwargs。
def print_kwargs(**kwargs):
# 打印kwargs的类型(是字典)
print("kwargs的类型:", type(kwargs))
# 遍历输出所有关键字参数(键值对)
for key, value in kwargs.items():
print(f"关键字参数 {key} = {value}")
# 调用函数,传入任意数量的关键字参数
print_kwargs(name="小明", age=18, city="北京")
print_kwargs(subject="数学", score=95) # 不同的关键字参数也可以
plaintext
kwargs的类型: <class 'dict'>
关键字参数 name = 小明
关键字参数 age = 18
关键字参数 city = 北京
kwargs的类型: <class 'dict'>
关键字参数 subject = 数学
关键字参数 score = 95
3. 结合使用(顺序很重要)
当函数同时有普通参数、*args、**kwargs 时,必须按以下顺序定义:普通参数 → *args → **kwargs
def mix_params(name, *args, **kwargs):
print(f"固定参数: {name}")
print("位置参数列表:", args)
print("关键字参数字典:", kwargs)
# 调用示例
mix_params("小红", 18, 170, city="上海", hobby="读书")
固定参数: 小红
位置参数列表: (18, 170)
关键字参数字典: {'city': '上海', 'hobby': '读书'}
二、实际应用场景
- 函数扩展:比如封装一个通用的打印函数,支持任意参数;
- 装饰器:装饰器需要适配被装饰函数的各种参数形式,
*args 和 **kwargs 是必备; - 调用其他函数:比如传递参数给另一个函数时,用
*args 解包位置参数,**kwargs 解包关键字参数:
def add(a, b):
return a + b
# 用*args解包元组作为位置参数
params = (3, 5)
print(add(*params)) # 输出 8
# 用**kwargs解包字典作为关键字参数
kwargs = {"a": 4, "b": 6}
print(add(**kwargs)) # 输出 10
总结
*args 接收任意数量的位置参数,打包成元组;**kwargs 接收任意数量的关键字参数,打包成字典;*args、**kwargs 名称可以修改,只要前面带 * 或 ** 就行。但强烈推荐用*args和**kwargs—— 这是 Python 开发者的通用约定;- 函数定义时,参数顺序必须是:普通参数 →
*args → **kwargs; - 核心价值是让函数支持可变数量的参数,提升代码的灵活性和通用性,常见于装饰器、通用工具函数等场景。