[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 参考文献

posted @ 2026-04-09 12:19  千千寰宇  阅读(15)  评论(0)    收藏  举报