Python函数的*args与**kwargs是什么?
摘要:本文详细解释 Python 中 def __init__(self, **kwargs): 的 **kwargs 用法。 1 Python 函数的 *args(可变参数元组) *args的用法 *args就是就是传递一个可变参数列表给函数实
本文详细解释 Python 中 def __init__(self, **kwargs): 的 **kwargs 用法。
1 Python 函数的 *args(可变参数元组)
*args的用法
*args就是就是传递一个可变参数列表给函数实参,这个参数列表的数目未知,甚至长度可以为0。
这段代码演示了如何使用args
def test_args(first, *args):
print('Required argument: ', first)
print(type(args))
for v in args:
print ('Optional argument: ', v)
test_args(1, 2, 3, 4)
第1个参数是必须要传入的参数,所以使用了第一个形参;
而后面3个参数则作为可变参数列表传入了实参,并且是作为元组tuple来使用的。
//代码的运行结果:
Required argument: 1
<class 'tuple'>
Optional argument: 2
Optional argument: 3
Optional argument: 4
补充说明: Python 中的元组(tuple) ,区别于 列表(list)
特性
列表 list
元组 tuple
可变性
✅ 可变(Mutable)
❌ 不可变(Immutable)
语法
[1, 2, 3]
(1, 2, 3) 或 1, 2, 3
性能
较慢
更快(内存占用更小)
用途
存储可变数据
存储固定数据、作为字典键
方法数量
多(增删改查)
少(仅查询)
2 Python 函数的 **kwargs(可变参数字典)
**kwargs的用法
而**kwargs则是将一个可变的关键字参数的字典传给函数实参,同样参数列表长度可以为0或为其他值
def test_kwargs(first, *args, **kwargs):
print('Required argument: ', first)
print(type(kwargs))
for v in args:
print ('Optional argument (args): ', v)
for k, v in kwargs.items():
print ('Optional argument %s (kwargs): %s' % (k, v))
test_kwargs(1, 2, 3, 4, k1=5, k2=6)
正如前面所说的,args类型是一个tuple,而kwargs则是一个字典dict,并且args只能位于kwargs的前面。代码的运行结果如下
Required argument: 1
<class 'dict'>
Optional argument (args): 2
Optional argument (args): 3
Optional argument (args): 4
Optional argument k2 (kwargs): 6
Optional argument k1 (kwargs): 5
什么是 **kwargs
**kwargs 是 Python 中用于接收任意数量的关键字参数的语法。它将传入的所有多余关键字参数打包成一个字典(dict)。
名称由来
kw = keyword(关键字)
args = arguments(参数)
** 表示解包/打包字典
基础用法示例
class Person:
def __init__(self, **kwargs):
# kwargs 是一个字典
print(f"kwargs 类型: {type(kwargs)}")
print(f"kwargs 内容: {kwargs}")
# 可以遍历或访问
for key, value in kwargs.items():
print(f"{key} = {value}")
# 动态设置属性
for key, value in kwargs.items():
setattr(self, key, value)
# 使用
p = Person(name="Alice", age=25, city="Beijing")
# 输出:
# kwargs 类型: <class 'dict'>
# kwargs 内容: {'name': 'Alice', 'age': 25, 'city': 'Beijing'}
# name = Alice
# age = 25
# city = Beijing
print(p.name) # Alice
print(p.age) # 25
常见使用场景
1. 灵活的类初始化(接受任意属性)
class Config:
def __init__(self, **kwargs):
# 设置默认值
self.debug = False
self.timeout = 30
self.host = "localhost"
# 用传入的参数覆盖默认值
for key, value in kwargs.items():
setattr(self, key, value)
# 使用
cfg = Config(debug=True, port=8080)
print(cfg.debug) # True
print(cfg.timeout) # 30 (默认值)
print(cfg.port) # 8080
2. 配合父类初始化(super)
class Animal:
def __init__(self, name, **kwargs):
self.name = name
print(f"Animal: {name}")
class Dog(Animal):
def __init__(self, name, breed, **kwargs):
super().__init__(name, **kwargs) # 把多余的参数传给父类
self.breed = breed
print(f"Dog: {breed}")
# 使用
d = Dog(name="Buddy", breed="Golden", age=3, color="brown")
# 输出:
# Animal: Buddy
# Dog: Golden
# age 和 color 被 Animal 接收(虽然示例中没使用)
3. 多层继承传递参数
class A:
def __init__(self, a, **kwargs):
self.a = a
super().__init__(**kwargs) # 继续传递
class B:
def __init__(self, b, **kwargs):
self.b = b
super().__init__(**kwargs)
class C(A, B):
def __init__(self, a, b, c):
super().__init__(a=a, b=b) # 自动按 MRO 传递
self.c = c
c = C(1, 2, 3)
print(c.a, c.b, c.c) # 1 2 3
**kwargs 的解包操作:既可收集动态参数,也可【展开】字典
不仅可以在定义函数时收集参数,还可以在调用函数时展开字典:
def greet(name, age, city):
print(f"{name}, {age}岁, 来自{city}")
# 字典解包
data = {"name": "Bob", "age": 30, "city": "Shanghai"}
greet(**data) # 等价于 greet(name="Bob", age=30, city="Shanghai")
完整对比:*args vs **kwargs
语法
接收形式
调用方式
内部类型
*args
多余的位置参数
func(1, 2, 3)
元组 tuple
**kwargs
多余的关键字参数
func(a=1, b=2)
字典 dict
def demo(a, b, *args, **kwargs):
print(f"a={a}, b={b}")
print(f"args={args}") # 元组
print(f"kwargs={kwargs}") # 字典
demo(1, 2, 3, 4, 5, x=10, y=20)
# 输出:
# a=1, b=2
# args=(3, 4, 5)
# kwargs={'x': 10, 'y': 20}
实际应用:ORM/模型类
class Model:
def __init__(self, **kwargs):
for key, value in kwargs.items():
if hasattr(self, key): # 只设置已定义的字段
setattr(self, key, value)
else:
raise AttributeError(f"未知属性: {key}")
class User(Model):
name = ""
email = ""
age = 0
u = User(name="Tom", email="tom@example.com")
print(u.name) # Tom
# u = User(unknown="x") # 报错:未知属性
总结
要点
说明
**kwargs 的本质
字典,包含所有多余的关键字参数
主要用途
灵活接收参数、参数透传、配置类
命名习惯
叫 kwargs 是约定,可以改
解包语法
**字典 可将字典展开为关键字参数
**kwargs 是 Python 实现灵活接口和代码复用的重要工具,在框架开发、API 设计、继承体系中非常常见。
X 参考文献
Python中的*args和**kwargs - Zhihu
