函数参数里的 *args 和 **kwargs
Python 函数使用 *args 和 **kwargs 可以接收任意数量的参数,是编写灵活函数的关键。
1. *args - 可变位置参数
*args 将多余的位置参数收集为元组。
基本用法
def sum_all(*args):
print(args) # (1, 2, 3, 4, 5)
return sum(args)
result = sum_all(1, 2, 3, 4, 5)
print(result) # 15
参数顺序
def greet(name, *args, greeting="Hello"):
print(f"{greeting}, {name}!")
if args:
print(f"还有: {args}")
greet("Alice", "Bob", "Carol", greeting="Hi")
# 输出:
# Hi, Alice!
# 还有: ('Bob', 'Carol')
2. **kwargs - 可变关键字参数
**kwargs 将多余的关键字参数收集为字典。
基本用法
def info(**kwargs):
print(kwargs) # {'name': 'Alice', 'age': 25, 'city': 'Beijing'}
info(name="Alice", age=25, city="Beijing")
结合使用
def func(required, *args, **kwargs):
print(f"必选: {required}")
print(f"可选位置: {args}")
print(f"可选关键字: {kwargs}")
func("必填参数", "可选1", "可选2", key1="value1", key2="value2")
# 输出:
# 必选: 必填参数
# 可选位置: ('可选1', '可选2')
# 可选关键字: {'key1': 'value1', 'key2': 'value2'}
3. 解包传参
使用 * 和 ** 可以将列表/字典解包为参数。
列表解包
def add(a, b, c):
return a + b + c
numbers = [1, 2, 3]
result = add(*numbers) # 相当于 add(1, 2, 3)
print(result) # 6
字典解包
def configure(host, port, timeout):
print(f"{host}:{port}, timeout={timeout}")
options = {"host": "localhost", "port": 8080, "timeout": 30}
configure(**options)
# 输出: localhost:8080, timeout=30
4. 实际应用
日志函数
def log(level, message, **kwargs):
print(f"[{level}] {message}")
if kwargs.get("extra"):
print(f"额外信息: {kwargs['extra']}")
log("INFO", "服务启动", extra={"port": 8080, "mode": "debug"})
装饰器
def debug(func):
def wrapper(*args, **kwargs):
print(f"调用 {func.__name__}")
print(f" args: {args}")
print(f" kwargs: {kwargs}")
result = func(*args, **kwargs)
print(f" 返回: {result}")
return result
return wrapper
@debug
def add(a, b):
return a + b
add(1, 2)
add(a=1, b=2)
可变参数函数
def average(*numbers):
if not numbers:
return 0
return sum(numbers) / len(numbers)
print(average(1, 2, 3, 4, 5)) # 3.0
print(average(10, 20)) # 15.0
5. 参数组合
全参数形式
def complete_func(
required, # 必选参数
*args, # 可变位置参数
keyword_only, # 仅关键字参数
**kwargs # 可变关键字参数
):
pass
仅关键字参数(Python 3)
def func(*, key_only):
print(key_only)
func(key_only="value")
# func("value") # TypeError
混合示例
def flexible_format(fmt, *args, **kwargs):
"""灵活的格式���函数"""
if args and kwargs:
# 位置参数 + 关键字参数
return fmt.format(*args, **kwargs)
elif args:
return fmt.format(*args)
elif kwargs:
return fmt.format(**kwargs)
else:
return fmt.format()
# 用法
flexible_format("{} {}", "Hello", "World")
flexible_format("{greeting} {name}", greeting="Hi", name="Alice")
flexible_format("{} {}", "Hi", name="Bob")
快速对照表
| 语法 | 说明 | 类型 |
|---|---|---|
*args |
收集多余位置参数 | tuple |
**kwargs |
收集多余关键字参数 | dict |
*list |
解包列表为位置参数 | - |
**dict |
解包字典为关键字参数 | - |
*, key |
强制关键字参数 | - |
*args 和 **kwargs 使函数更加灵活,是 Python 函数式编程的重要特性。