返回博客

16. 函数参数详解:位置、默认、可变与关键字参数

16. 函数参数详解:位置、默认、可变与关键字参数

第十六篇:函数参数详解——位置、默认、可变与关键字参数

前言

Python 函数的参数类型丰富而灵活。本文全面讲解位置参数、默认参数、可变参数 *args、关键字参数 **kwargs 以及命名关键字参数的用法和最佳实践。

位置参数

def greet(name, message):
    print(f"{message},{name}!")
greet("小明", "你好")      # 你好,小明!

**规则:**调用时参数数量必须与定义一致;默认按顺序从左到右匹配。

默认参数

def power(base, exp=2):
    return base ** exp
print(power(5))     # 25
print(power(5, 3))  # 125

⚠️ 可变默认参数陷阱

# ❌ 危险:可变对象作为默认值
def append_item(item, target=[]):
    target.append(item)
    return target  # 每次调用共享同一列表

# ✅ 正确做法:用 None 替代
def append_item(item, target=None):
    if target is None:
        target = []
    target.append(item)
    return target

可变位置参数 *args

def sum_all(*args):
    total = 0
    for num in args:
        total += num
    return total
print(sum_all(1, 2, 3))       # 6
print(sum_all(1, 2, 3, 4, 5)) # 15

*args 本质是 tuple 形式存储。

解包传参

values = [1, 2, 3]
print(add(*values))  # add 接收为 position args

关键字参数 **kwargs

def show_kwargs(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}={value}")
show_kwargs(name="小明", age=25)  # name=小明 / age=25

**kwargs 本质是 dict 形式存储。

解包传参反向操作

data = {"name": "小红", "age": 22}
print(create_user(**data))  # 字典解包为 keyword args

参数组合使用顺序

def complex_func(pos_only, pos_or_kw, /, pos_kw, *, kw_only):
    pass  # 展示各种参数类型的顺序
部分 语法 说明
仅位置参数 a, b, / / 之前只能位置传参
位置或关键字 c, d 默认行为
仅关键字参数 *, e, f * 之后只能关键字传参

Python 3.8+ 新增特性

def divide(a, b, /):  # a, b 只能用位置传参
    return a // b, a % b
divide(10, 3)          # ✅
# divide(a=10, b=3)    # ❌ SyntaxError!

完整参数示例

def make_profile(name, age, *tags, city="未知", bio="", **extra):
    profile = {"name": name, "age": age, "tags": list(tags), "city": city, "bio": bio}
    profile.update(extra)
    return profile
result = make_profile("小明", 25, "程序员", "Python", city="北京", bio="热爱编程")

实战:通用数据转换器

def convert_data(data: dict, **transformations: callable) -> dict:
    result = data.copy()
    for field, transform in transformations.items():
        if field in result:
            result[field] = transform(result[field])
    return result
raw_data = {"score": 92.567, "name": " 小明  ", "id": "001"}
cleaned = convert_data(raw_data, score=float, name=str.strip, id=lambda x: int(x.lstrip("0")))

总结

  1. 位置参数 — 按顺序匹配,数量必须一致
  2. 默认参数 — 提供默认值,注意可变对象的陷阱
  3. 默认参数顺序 — 默认值必须在非默认值之后
  4. *args — 可变位置参数,以 tuple 形式存储
  5. 解包传参 — *list 将序列解包为位置参数
  6. **kwargs — 可变关键字参数,以 dict 形式存储
  7. 解包传参 — **dict 将字典解包为关键字参数
  8. 参数组合顺序 — 位置 → / → 混合 → * → 仅关键字
  9. 实战应用 — 通用数据转换器、配置合并等

下一篇文章将深入讲解递归函数:原理与经典案例。


本文是 Python 教程系列的第十六篇。