Python 中的 *args 和 **kwargs

66 阅读3分钟

Python 中的 *args 和 **kwargs

这两个是 Python 中非常强大的特性,它们主要用于函数定义,允许你向函数传递可变数量的参数。


1. *args(非关键字可变参数)

*args 用于接收任意数量的非关键字参数( positional arguments),并将其放入一个元组(tuple)  中。

  • * 是解包操作符。
  • args 只是一个约定俗成的名字,你可以使用任何你喜欢的名字(例如 *vars),但使用 *args 是最佳实践,能让代码更易读。

何时使用?
当你不确定函数会接收多少个非关键字参数时。

示例:

def sum_numbers(*args):
    print(f"接收到的参数(元组): {args}")
    total = 0
    for num in args:
        total += num
    return total

# 调用函数
result1 = sum_numbers(1, 2)
print(result1) # 输出: 接收到的参数(元组): (1, 2) \n 3

result2 = sum_numbers(10, 20, 30, 40, 50)
print(result2) # 输出: 接收到的参数(元组): (10, 20, 30, 40, 50) \n 150

# 甚至可以没有参数
result3 = sum_numbers()
print(result3) # 输出: 接收到的参数(元组): () \n 0

另一个重要用途:解包列表/元组

你可以在函数调用时使用 * 来将一个列表或元组解包成一串独立的参数传入函数。

def my_function(a, b, c):
    print(a, b, c)

my_list = [1, 2, 3]
my_tuple = (4, 5, 6)

# 不使用 *,整个列表会被当作一个参数 a
# my_function(my_list) 这会报错,因为 b 和 c 缺少参数

# 使用 * 解包
my_function(*my_list) # 输出: 1 2 3
my_function(*my_tuple) # 输出: 4 5 6

2. **kwargs(关键字可变参数)

**kwargs 用于接收任意数量的关键字参数( keyword arguments),并将其放入一个字典(dictionary)  中。

  • ** 是解包操作符,用于键值对。
  • kwargs 同样是约定俗成的名字,意思是 "keyword arguments"。

何时使用?
当你不确定函数会接收多少个关键字参数时。

示例:

def introduce_yourself(**kwargs):
    print(f"接收到的参数(字典): {kwargs}")
    for key, value in kwargs.items():
        print(f"{key}: {value}")

# 调用函数
introduce_yourself(name="Alice", age=30, job="Engineer")
# 输出:
# 接收到的参数(字典): {'name': 'Alice', 'age': 30, 'job': 'Engineer'}
# name: Alice
# age: 30
# job: Engineer

introduce_yourself(country="Japan", language="Japanese")
# 输出:
# 接收到的参数(字典): {'country': 'Japan', 'language': 'Japanese'}
# country: Japan
# language: Japanese

另一个重要用途:解包字典

你可以在函数调用时使用 ** 来将一个字典解包成关键字参数传入函数。

def greet_person(name, message):
    print(f"Hello {name}, {message}")

my_dict = {'name': 'Bob', 'message': 'how are you?'}

# 使用 ** 解包字典
greet_person(**my_dict) # 输出: Hello Bob, how are you?
# 这等价于:
# greet_person(name='Bob', message='how are you?')

3. 组合使用:标准参数顺序

在定义一个函数时,如果需要同时使用多种参数,它们必须遵循严格的顺序:

标准顺序:(普通参数, *args, 关键字参数, **kwargs)

def complex_function(a, b, *args, default_param="Hi", **kwargs):
    print(f"a: {a}")
    print(f"b: {b}")
    print(f"args: {args}")
    print(f"default_param: {default_param}")
    print(f"kwargs: {kwargs}")

# 调用示例
complex_function(1, 2, 3, 4, 5, default_param="Hello", x=10, y=20, z=30)

输出:

a: 1
b: 2
args: (3, 4, 5)        # 3,4,5 被 *args 捕获
default_param: Hello   # 明确指定的关键字参数
kwargs: {'x': 10, 'y': 20, 'z': 30} # 其他关键字参数被 **kwargs 捕获

错误示例:
将 *args 放在 **kwargs 后面是不允许的,会引发语法错误。

def wrong_function(a, **kwargs, *args): # SyntaxError: invalid syntax
    ...

总结

特性语法捕获内容数据类型主要用途
非关键字可变参数*args多余的非关键字参数元组 (Tuple)1. 函数定义:接收任意数量参数 2. 函数调用:解包序列
关键字可变参数**kwargs多余的关键字参数字典 (Dictionary)1. 函数定义:接收任意数量关键字参数 2. 函数调用:解包字典

掌握 *args 和 **kwargs 可以让你编写出非常灵活和通用的函数,是 Python 函数高级用法的基础。