Python中的魔法参数*args 和 **kwargs
在定义函数时,你可能无法提前确定用户会传入多少个参数。*args 和 **kwargs 就是用来处理这种可变数量参数的工具:
*args:接收任意数量的位置参数(非键值对形式),并将它们打包成一个元组 (tuple)。**kwargs:接收任意数量的关键字参数(键值对形式),并将它们打包成一个字典 (dict)。
注意:
args和kwargs只是约定俗成的命名,你可以改成其他名字(比如*params、**kwargs_dict),但强烈建议遵守约定,让代码更易读。
一、*args 的用法
1. 基础示例
def sum_numbers(*args):
"""计算任意数量数字的和"""
total = 0
# args 是一个元组,可以遍历
for num in args:
total += num
return total
# 调用方式1:传入多个位置参数
print(sum_numbers(1, 2, 3)) # 输出:6
# 调用方式2:解包列表/元组传入(加*)
nums = [4, 5, 6]
print(sum_numbers(*nums)) # 输出:15
2. 结合普通参数使用
*args 必须放在普通位置参数之后:
def print_info(name, *args):
print(f"姓名:{name}")
print(f"其他信息:{args}")
print_info("张三", 25, "北京", "程序员")
# 输出:
# 姓名:张三
# 其他信息:(25, '北京', '程序员')
二、**kwargs 的用法
1. 基础示例
def print_person(**kwargs):
"""打印个人信息(键值对形式)"""
for key, value in kwargs.items():
print(f"{key}:{value}")
# 调用方式1:传入多个关键字参数
print_person(name="李四", age=30, city="上海")
# 输出:
# name:李四
# age:30
# city:上海
# 调用方式2:解包字典传入(加**)
person_info = {"name": "王五", "age": 28, "job": "设计师"}
print_person(**person_info)
# 输出:
# name:王五
# age:28
# job:设计师
2. 结合普通参数、*args 使用
参数顺序必须是: 普通参数 → *args → **kwargs:
def func(a, b, *args, **kwargs):
print(f"普通参数a:{a}")
print(f"普通参数b:{b}")
print(f"args:{args}")
print(f"kwargs:{kwargs}")
func(1, 2, 3, 4, 5, x=10, y=20)
# 输出:
# 普通参数a:1
# 普通参数b:2
# args:(3, 4, 5)
# kwargs:{'x': 10, 'y': 20}
三、实际应用场景
-
封装通用函数
:比如写一个日志函数,支持传入任意附加信息:
def log(level, message, **kwargs): print(f"[{level}] {message}") if kwargs: print("附加信息:", kwargs) log("INFO", "用户登录成功", user_id=1001, ip="127.0.0.1") -
函数装饰器
:装饰器需要兼容被装饰函数的任意参数,必须用
*args和**kwargs:def decorator(func): def wrapper(*args, **kwargs): print("函数执行前的操作") result = func(*args, **kwargs) # 传递所有参数给原函数 print("函数执行后的操作") return result return wrapper @decorator def add(a, b): return a + b print(add(3, 5)) # 输出:8(同时会打印前后操作)
总结
*args接收任意数量的位置参数,打包成元组;**kwargs接收任意数量的关键字参数,打包成字典。- 参数定义顺序必须是:普通参数 →
*args→**kwargs,调用时可通过*/**解包列表 / 字典传入。 - 核心作用是让函数支持可变数量的参数,常用于通用函数、装饰器、类的继承等场景。

浙公网安备 33010602011771号