首页 / Python3 入门教程 / 函数参数详解

Python3 入门教程

函数参数详解

本教程共 70 篇 · 第 22 篇 · 更新于 2026-07-22 · 约 2 分钟阅读

PythonPython3 入门教程函数参数*args**kwargs默认参数

22. 函数参数详解

本节目标:掌握位置参数、默认参数、可变参数和关键字参数,能写出灵活易用的函数接口。

位置参数

最普通的参数,按位置顺序匹配:

def power(base, exponent):
    return base ** exponent

print(power(2, 3))   # 8,base=2, exponent=3

默认参数

给参数指定默认值,调用时可以不传:

def power(base, exponent=2):
    return base ** exponent

print(power(3))      # 9,exponent 用默认值 2
print(power(2, 3))   # 8,exponent 传入 3
Warning

默认参数必须指向不可变对象。用可变对象当默认值是大坑:

def add_item(item, items=[]):
    items.append(item)
    return items

print(add_item(1))   # [1]
print(add_item(2))   # [1, 2]  怎么还记着上次的?

因为默认参数在函数定义时就被计算出来了,所有调用共享同一个列表。正确做法:

def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

关键字参数

调用时指定参数名,不用管顺序:

def create_user(name, age, city="Beijing"):
    print(f"{name}, {age}岁, {city}")

create_user("Alice", 25)
create_user("Bob", 30, city="Shanghai")
create_user(age=20, name="Charlie")   # 用关键字传参,顺序随意

可变参数 *args

参数个数不确定时,用 *args 收集多余的位置参数:

def total(*numbers):
    result = 0
    for n in numbers:
        result += n
    return result

print(total())           # 0
print(total(1, 2, 3))    # 6
print(total(1, 2, 3, 4, 5))   # 15

函数内部,numbers 是一个元组:

def show_args(*args):
    print(args)
    print(type(args))

show_args(1, "hello", True)
# (1, 'hello', True)
# <class 'tuple'>

如果已经有一个列表或元组,用 * 拆开传进去:

nums = [1, 2, 3, 4]
print(total(*nums))   # 10,等价于 total(1, 2, 3, 4)
Tip

*args 里的 args 只是约定俗成的名字,可以改。但别改,这是行业共识。

关键字可变参数 **kwargs

收集多余的关键字参数:

def show_info(**kwargs):
    print(kwargs)
    print(type(kwargs))

show_info(name="Alice", age=25)
# {'name': 'Alice', 'age': 25}
# <class 'dict'>

如果已经有一个字典,用 ** 拆开传进去:

data = {"name": "Bob", "age": 30}
show_info(**data)   # 等价于 show_info(name="Bob", age=30)

参数组合顺序

定义函数时,参数顺序必须是:

**位置参数 → 默认参数 → *args → kwargs

def func(a, b=2, *args, **kwargs):
    print(f"a={a}, b={b}, args={args}, kwargs={kwargs}")

func(1)                          # a=1, b=2, args=(), kwargs={}
func(1, 3)                       # a=1, b=3, args=(), kwargs={}
func(1, 3, 4, 5)                 # a=1, b=3, args=(4, 5), kwargs={}
func(1, 3, 4, x=10, y=20)        # a=1, b=3, args=(4,), kwargs={'x':10,'y':20}
Note

如果默认参数后面还有 *args,给默认参数传值时必须用关键字:

func(1, x=10)   # 正确

强制关键字参数

如果参数列表里有 *,它后面的参数必须用关键字传入:

def safe_divide(a, b, *, strict=False):
    if strict and b == 0:
        raise ValueError("除数不能为 0")
    return a / b

safe_divide(10, 2, strict=True)   # 正确
safe_divide(10, 2, True)          # TypeError

这在参数很多、容易混淆时很有用,能显著提高代码可读性。

综合示例

def log_message(level, msg, *args, timestamp=None, **kwargs):
    """记录日志消息。

    参数:
        level: 日志级别
        msg: 消息模板
        *args: 模板中的占位符值
        timestamp: 是否包含时间戳
        **kwargs: 额外信息
    """
    formatted = msg % args
    if timestamp:
        from datetime import datetime
        formatted = f"[{datetime.now()}] {formatted}"
    print(f"[{level}] {formatted}")
    for k, v in kwargs.items():
        print(f"  {k}: {v}")

log_message("INFO", "用户 %s 登录", "Alice", timestamp=True, ip="192.168.1.1")

来源:参考了 runoob「Python3 函数」、liaoxuefeng「函数的参数」等,改写后所得。