Python中的*args和**kwargs是什么?
在 Python 中,*args 和 **kwargs 是用于在函数定义中处理可变数量参数的特殊语法。
简单来说,它们允许你传递任意数量的参数给一个函数,而不需要预先定义好参数的个数。
以下是详细的解释:
1. *args (Non-Keyword Arguments)
- 含义:用于接收任意数量的位置参数(Positional Arguments)。
- 数据结构:在函数内部,
args会被打包成一个元组 (Tuple)。 - 语法核心:核心在于星号
*,args只是一个约定俗成的名字(你可以写成*vars或*names,但强烈建议遵守*args的惯例)。
示例:
python
def sum_numbers(*args):
# args 在这里是一个元组,例如 (1, 2, 3)
print(f"args 的类型: {type(args)}")
print(f"args 的内容: {args}")
total = 0
for num in args:
total += num
return total
print(sum_numbers(1, 2, 3))
# 输出: 6
print(sum_numbers(10, 20))
# 输出: 30
2. kwargs (Keyword Arguments)
- 含义:用于接收任意数量的关键字参数(Keyword Arguments)。
- 数据结构:在函数内部,
kwargs会被打包成一个字典 (Dictionary)。 - 语法核心:核心在于双星号
,kwargs代表 "Keyword Arguments"。
示例:
python
def print_info(kwargs):
# kwargs 在这里是一个字典,例如 {'name': 'Alice', 'age': 30}
print(f"kwargs 的类型: {type(kwargs)}")
print(f"kwargs 的内容: {kwargs}")
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=30, city="New York")
# 输出:
# name: Alice
# age: 30
# city: New York
3. 组合使用与参数顺序
你可以在同一个函数中同时使用普通参数、*args 和 **kwargs。但是,顺序非常重要,必须严格遵守以下顺序:
- 普通位置参数 (Standard arguments)
*args**kwargs
语法:def func(fargs, *args, **kwargs):
示例:
python
def complex_function(title, *args, **kwargs):
print(f"标题: {title}")
print(f"位置参数 (args): {args}")
print(f"关键字参数 (kwargs): {kwargs}")
complex_function("测试数据", 1, 2, 3, author="Tom", date="2023-10-01")
# 输出:
# 标题: 测试数据
# 位置参数 (args): (1, 2, 3)
# 关键字参数 (kwargs): {'author': 'Tom', 'date': '2023-10-01'}
4. 进阶:使用 * 和 ** 进行解包 (Unpacking)
除了在函数定义时使用,* 和 ** 也可以在函数调用时使用,用于将列表/元组或字典“解包”成独立的参数传递给函数。
示例:
python
def introduce(name, age, city):
print(f"我叫 {name}, 今年 {age} 岁, 来自 {city}。")
# 1. 解包列表/元组
info_list = ["Bob", 25, "London"]
introduce(*info_list)
# 等同于 introduce("Bob", 25, "London")
# 2. 解包字典
info_dict = {"name": "Charlie", "city": "Paris", "age": 40}
introduce(**info_dict)
# 等同于 introduce(name="Charlie", city="Paris", age=40)
总结:什么时候使用它们?
- 装饰器 (Decorators):当你编写装饰器时,通常不知道被装饰的函数接收什么参数,所以使用
*args和**kwargs来传递所有参数。 - 子类化 (Subclassing):当你重写父类的方法但又想调用父类方法时(
super().__init__(*args, **kwargs)),这样可以避免代码在父类参数变更时崩溃。 - 灵活性:当你无法预知用户会传递多少参数时(例如
print()函数或pandas中的某些配置函数)。
一句话总结:
*args把多余的位置参数打包成元组。**kwargs把多余的关键字参数打包成字典。
右滑查看面试常问