[Python] Python 函数的 `*args 与 **kwargs`
本文详细解释 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 参考文献
本文作者:
千千寰宇
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!

浙公网安备 33010602011771号