欢迎光临
我们一直在努力

第12课:Python|函数进阶【位置参数、关键字参数、默认参数、不定长参数全解】

在这里插入图片描述

文章目录

  • 📖 开篇导读
  • 🎯 学习目标
  • 📚 知识点理论精讲
    • 一、回顾与深入:位置参数与关键字参数
      • 1.1 位置参数(Positional Arguments)
      • 1.2 关键字参数(Keyword Arguments)
      • 1.3 位置参数和关键字参数的混用规则
    • 二、默认参数(Default Arguments)
      • 2.1 基本用法
      • 2.2 默认参数的求值时机
      • 2.3 可变默认参数的陷阱及解决方案
      • 2.4 默认参数的位置限制
    • 三、不定长参数(可变参数)
      • 3.1 `*args` —— 接收任意多个位置参数
      • 3.2 `**kwargs` —— 接收任意多个关键字参数
      • 3.3 同时使用`*args`和`**kwargs`
      • 3.4 `*args`和`**kwargs`的名称可以自定义
    • 四、仅限关键字参数(Keyword-Only Arguments)
      • 4.1 在`*args`之后定义
      • 4.2 使用单独的`*`分隔
      • 4.3 应用场景
    • 五、参数解包(Unpacking)
      • 5.1 解包序列(列表、元组等)为位置参数
      • 5.2 解包字典为关键字参数
      • 5.3 混合使用解包
      • 5.4 解包的应用场景
    • 六、参数组合的完整顺序
  • 💻 代码案例实操
    • 案例1:参数组合全面练习
    • 案例2:可变默认参数陷阱深度剖析
    • 案例3:`*args`和`**kwargs`实现通用装饰器(预热)
    • 案例4:参数解包的实战应用
    • 案例5:仅限关键字参数设计清晰的API
    • 案例6:综合实战——灵活的参数设计
  • ⚠️ 易错点避坑总结
  • 📝 课后实战练习题
      • 第1题:参数顺序练习
      • 第2题:默认参数陷阱修复
      • 第3题:使用`*args`实现通用求和
      • 第4题:关键字参数与仅限关键字参数
      • 第5题:参数解包练习
      • 第6题:设计灵活的函数
      • 第7题:综合应用题——函数参数解析器
  • 🧠 知识点思维导图总结
  • 🔜 下节课预告
    • 第13课:局部变量、全局变量、函数作用域与闭包基础精讲
  • 🔗《50节课 Python 从入门到精通》系列课程导航

📖 开篇导读

上一节课我们学习了函数的基本概念:定义、调用、参数和返回值。但是,Python函数的参数机制远比表面看到的要丰富和强大。在实际开发中,你会遇到各种参数传递的需求:有些参数必须按顺序传递,有些可以通过名字传递,有些参数可有可无且有默认值,有些参数可以接收任意多个值,甚至可以将列表或字典“拆开”作为参数传入。

💡 工作场景:在大型项目中,函数往往有多个参数。合理运用默认参数可以提高函数的易用性(比如print函数的sep和end);使用*args和**kwargs可以编写高度通用的装饰器、适配器;参数解包让API调用更加简洁。

本课将深入剖析Python函数的参数体系,包括:

  • 位置参数与关键字参数的区别与混用规则
  • 默认参数的最佳实践及可变默认参数的陷阱
  • *args和**kwargs的打包与解包机制
  • 仅限关键字参数(Keyword-Only Arguments)
  • 参数解包:将序列和字典作为参数传入

学完本课,你将全面掌握Python函数的参数用法,能够设计出灵活且健壮的API。


🎯 学习目标

目标编号具体掌握内容对应面试/工作价值
1️⃣ 深入理解位置参数与关键字参数的区别及混用规则 写出更清晰、更灵活的函数调用
2️⃣ 掌握默认参数的正确用法及可变默认参数的陷阱与解决方案 防止隐蔽bug,面试高频题
3️⃣ 熟练使用*args接收任意数量的位置参数 编写通用的装饰器、累加器等
4️⃣ 熟练使用**kwargs接收任意数量的关键字参数 处理配置、扩展参数
5️⃣ 理解仅限关键字参数的定义与使用场景 设计明确的API,避免参数顺序混淆
6️⃣ 掌握参数解包(使用*和**在函数调用时) 简化代码,提高可读性

🔥 面试考点:面试官常问“*args和**kwargs的作用是什么?”“如何将列表作为位置参数传入函数?”“默认参数为什么不能是可变对象?”“什么是仅限关键字参数?如何定义?”


📚 知识点理论精讲

一、回顾与深入:位置参数与关键字参数

1.1 位置参数(Positional Arguments)

位置参数是最常见的参数形式。调用函数时,传入的值的顺序必须与函数定义的参数顺序一致。

def introduce(name, age, city):
print(f"{name}, {age}岁, 来自{city}")

# 位置参数调用
introduce("张三", 25, "北京") # 正确

如果位置数量不匹配,会报TypeError。

1.2 关键字参数(Keyword Arguments)

调用时使用参数名=值的形式,可以忽略顺序。

introduce(city="上海", name="李四", age=30) # 正确

💡 工作应用:当函数有多个参数且有些参数有默认值时,使用关键字参数可以只指定需要修改的参数,提高可读性。

1.3 位置参数和关键字参数的混用规则

  • 位置参数必须在关键字参数之前。
  • 同一个参数不能同时以位置和关键字形式传递。

# 正确
introduce("王五", city="广州", age=28)

# 错误:关键字参数之后不能有位置参数
# introduce(city="深圳", "赵六", 22) # SyntaxError

# 错误:同一个参数重复
# introduce("赵六", name="赵六", age=22) # TypeError


二、默认参数(Default Arguments)

在函数定义时,可以为参数指定默认值。调用时如果不提供该参数,则使用默认值。

2.1 基本用法

def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")

greet("小明") # Hello, 小明!
greet("小红", "Hi") # Hi, 小红!
greet("小刚", greeting="Hey") # 关键字形式

2.2 默认参数的求值时机

默认参数的值在函数定义时被计算一次,而不是每次调用时重新计算。这会导致一个经典陷阱:使用可变对象作为默认参数。

import time

def log_time(msg, when=time.time()):
print(f"[{when}] {msg}")

log_time("first") # 时间戳T1
time.sleep(2)
log_time("second") # 时间戳仍然是T1,因为when默认值在定义时已固定

2.3 可变默认参数的陷阱及解决方案

# 错误示例
def add_item(item, lst=[]):
lst.append(item)
return lst

print(add_item(1)) # [1]
print(add_item(2)) # [1, 2] ← 累积了

原理:默认参数[]在函数定义时创建,之后每次调用如果不传lst,使用的都是同一个列表对象。

解决方案:使用None作为默认值,在函数内部重新创建可变对象。

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

print(add_item(1)) # [1]
print(add_item(2)) # [2]

🔥 面试考点:“为什么默认参数不能用可变对象?”答:因为默认参数在定义时创建,多次调用共享同一个对象,导致状态累积。应使用None作为哨兵值。

2.4 默认参数的位置限制

默认参数必须放在非默认参数(位置参数)之后。

# 正确
def func(a, b=10, c=20): pass

# 错误:默认参数后不能有位置参数
# def func(a=10, b): pass # SyntaxError


三、不定长参数(可变参数)

当你无法预知函数会接收多少个参数时,可以使用*args和**kwargs。

3.1 *args —— 接收任意多个位置参数

*args将传入的额外位置参数打包成一个元组。参数名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(10, 20, 30, 40)) # 100
print(sum_all()) # 0(元组为空)

3.2 **kwargs —— 接收任意多个关键字参数

**kwargs将传入的额外关键字参数打包成一个字典。

def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")

print_info(name="张三", age=25, city="北京")
# 输出:
# name: 张三
# age: 25
# city: 北京

3.3 同时使用*args和**kwargs

两者可以同时使用,*args必须在**kwargs之前。

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

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

3.4 *args和**kwargs的名称可以自定义

语法要求是*和**,后面的名称可以随意,但args和kwargs是强烈推荐的惯例。

def func(*numbers, **options):
pass


四、仅限关键字参数(Keyword-Only Arguments)

在Python 3中,可以定义必须使用关键字传递的参数。有两种定义方式:

4.1 在*args之后定义

def func(a, b, *args, c, d=10):
print(a, b, args, c, d)

# 调用
func(1, 2, 3, 4, c=5) # c必须用关键字
# func(1,2,3,4,5) # 错误,c缺少关键字

这里的c和d(d有默认值可选)是仅限关键字参数,不能通过位置传递。

4.2 使用单独的*分隔

如果不希望接收任意数量的位置参数,只想强制关键字参数,可以使用单独的*。

def func(a, b, *, c, d=10):
print(a, b, c, d)

func(1, 2, c=3) # 正确
# func(1,2,3) # 错误,c必须关键字
# func(1,2,c=3,d=20) # 正确

4.3 应用场景

  • 当参数名本身已经足够说明含义,强制使用关键字提高可读性。
  • API设计中,某些参数在未来可能增加,使用仅限关键字可以避免破坏调用顺序。
  • 避免参数过多时位置混淆。

# 实际示例:open函数的部分参数就是仅限关键字(如encoding)
with open("file.txt", "r", encoding="utf-8") as f:
pass


五、参数解包(Unpacking)

参数解包是*和**在函数调用时的用法,与定义时的*args/**kwargs相对。

5.1 解包序列(列表、元组等)为位置参数

def add(a, b, c):
return a + b + c

nums = [10, 20, 30]
result = add(*nums) # 相当于 add(10, 20, 30)
print(result) # 60

5.2 解包字典为关键字参数

def person(name, age, city):
print(f"{name}, {age}, {city}")

data = {"name": "张三", "age": 25, "city": "北京"}
person(**data) # 相当于 person(name="张三", age=25, city="北京")

5.3 混合使用解包

def func(a, b, c, d=0):
print(a,b,c,d)

args = (1, 2)
kwargs = {"c": 3, "d": 4}
func(*args, **kwargs) # 1 2 3 4

5.4 解包的应用场景

  • 当已经有列表/字典参数,需要传递给函数时,避免手动索引。
  • 合并多个字典:{**d1, **d2}(Python 3.5+)。
  • 调用继承的父类方法:super().__init__(**kwargs)。

六、参数组合的完整顺序

在函数定义中,所有参数必须遵循以下顺序:

  • 位置参数(普通参数)
  • 默认参数(普通参数带默认值)
  • *args(可变位置参数)
  • 仅限关键字参数(可以在*args之后,或者在单独的*之后)
  • **kwargs(可变关键字参数)
  • def full_example(a, b, c=10, *args, d=20, e, **kwargs):
    print(a, b, c, args, d, e, kwargs)

    # 调用示例
    full_example(1, 2, 3, 4, 5, e=30, f=40, g=50)
    # a=1, b=2, c=3, args=(4,5), d=20, e=30, kwargs={'f':40, 'g':50}

    注意:d有默认值但位于*args之后,所以d也是仅限关键字参数(可以通过关键字覆盖默认值)。


    💻 代码案例实操

    案例1:参数组合全面练习

    """
    param_combos.py
    演示各种参数组合的定义与调用
    """

    # 1. 位置参数 + 默认参数
    def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

    greet("Alice")
    greet("Bob", "Hi")

    # 2. 位置参数 + *args
    def print_scores(name, *scores):
    print(f"{name} 的成绩: {scores}")

    print_scores("张三", 85, 92, 78)
    print_scores("李四") # 空元组

    # 3. *args + 仅限关键字参数(*args后的参数必须用关键字)
    def record_purchase(customer, *items, discount=0.0):
    print(f"顾客: {customer}")
    print(f"商品: {items}")
    print(f"折扣: {discount}%")

    record_purchase("王五", "手机", "电脑", discount=10)

    # 4. 单独的* 强制仅限关键字参数
    def configure(host, port, *, ssl=False, timeout=30):
    print(f"Host: {host}, Port: {port}, SSL: {ssl}, Timeout: {timeout}")

    configure("localhost", 8080, ssl=True, timeout=60)
    # configure("localhost", 8080, True, 60) # 错误,必须用关键字

    # 5. **kwargs
    def log_event(event, **details):
    print(f"事件: {event}")
    for k, v in details.items():
    print(f" {k}: {v}")

    log_event("登录", user="admin", ip="192.168.1.1", result="success")

    # 6. 大杂烩
    def full(a, b=10, *args, c=20, d, **kwargs):
    print(f"a={a}, b={b}, args={args}, c={c}, d={d}, kwargs={kwargs}")

    full(1, 2, 3, 4, d=30, e=40) # a=1,b=2,args=(3,4),c=20,d=30,kwargs={'e':40}

    案例2:可变默认参数陷阱深度剖析

    """
    mutable_default_trap.py
    演示默认参数的陷阱及多种解决方案
    """

    print("=== 错误示例 ===")
    def accumulate_wrong(value, storage=[]):
    storage.append(value)
    return storage

    print(accumulate_wrong(1)) # [1]
    print(accumulate_wrong(2)) # [1, 2] ← 意外累积
    print(accumulate_wrong(3)) # [1, 2, 3]

    print("\\n=== 解决方案1:None哨兵 ===")
    def accumulate_correct1(value, storage=None):
    if storage is None:
    storage = []
    storage.append(value)
    return storage

    print(accumulate_correct1(1)) # [1]
    print(accumulate_correct1(2)) # [2]

    print("\\n=== 解决方案2:不修改默认参数,返回新对象 ===")
    def accumulate_correct2(value, storage=[]):
    # 返回新列表,而不是修改原列表
    return storage + [value]

    print(accumulate_correct2(1)) # [1]
    print(accumulate_correct2(2)) # [2]

    print("\\n=== 解决方案3:使用元组(不可变)作为默认值 ===")
    def accumulate_correct3(value, storage=()):
    storage = storage + (value,)
    return storage

    print(accumulate_correct3(1)) # (1,)
    print(accumulate_correct3(2)) # (2,)

    # 如果需要共享同一个列表,应该显式传入
    print("\\n=== 共享列表的正确方式 ===")
    shared = []
    print(accumulate_correct1(10, shared)) # [10]
    print(accumulate_correct1(20, shared)) # [10, 20]

    案例3:*args和**kwargs实现通用装饰器(预热)

    装饰器是Python高级特性,但*args和**kwargs是实现通用装饰器的关键。此例仅展示参数传递,详细装饰器在第32课。

    """
    wrapper_demo.py
    演示*args和**kwargs在包装函数时的作用
    """

    def logger(func):
    """简单的日志装饰器,记录函数调用"""
    def wrapper(*args, **kwargs):
    print(f"调用函数: {func.__name__}")
    print(f"位置参数: {args}")
    print(f"关键字参数: {kwargs}")
    result = func(*args, **kwargs)
    print(f"返回值: {result}")
    return result
    return wrapper

    @logger
    def add(a, b):
    return a + b

    @logger
    def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

    # 调用被装饰的函数
    add(3, 5)
    greet("张三", greeting="Hi")

    # 可以看到,无论被包装的函数有多少参数,wrapper都能接收并传递

    案例4:参数解包的实战应用

    """
    unpacking_demo.py
    演示函数调用时的参数解包
    """

    # 1. 解包列表/元组
    def vector_add(v1, v2, v3):
    return v1 + v2 + v3

    coords = [10, 20, 30]
    print(vector_add(*coords)) # 相当于 vector_add(10,20,30)

    # 2. 解包字典
    def create_user(name, age, email):
    return f"User: {name}, Age: {age}, Email: {email}"

    user_data = {"name": "李华", "age": 28, "email": "lihua@example.com"}
    print(create_user(**user_data))

    # 3. 解包用于合并数据
    def save_record(id, **fields):
    print(f"ID: {id}")
    for k, v in fields.items():
    print(f" {k}: {v}")

    base = {"name": "王芳", "city": "上海"}
    extra = {"phone": "123456", "score": 95}
    save_record(1001, **base, **extra) # 合并两个字典作为关键字参数

    # 4. 解包在字符串格式化中的应用(Python 3.5+)
    values = {"name": "张三", "score": 98.5}
    print("{name}的成绩是{score:.1f}".format(**values))

    # 5. 优雅地处理函数参数传递
    def process(data, *args, **kwargs):
    # 有些内部函数需要同样的参数
    intermediate = data * 2
    return finalize(intermediate, *args, **kwargs)

    def finalize(value, multiplier=1, **options):
    return value * multiplier

    print(process(10, multiplier=3)) # 解包传递multiplier

    案例5:仅限关键字参数设计清晰的API

    """
    keyword_only_demo.py
    使用仅限关键字参数设计不易误用的API
    """

    # 场景:配置数据库连接
    def connect_db(host, port, *, user, password, timeout=30):
    """
    连接数据库,user和password必须使用关键字传入
    """

    print(f"连接到 {host}:{port}")
    print(f"用户: {user}, 超时: {timeout}秒")
    # 实际连接逻辑…
    return True

    # 正确调用
    connect_db("localhost", 3306, user="root", password="123456")
    connect_db("localhost", 3306, user="root", password="123456", timeout=60)

    # 错误调用(试图使用位置参数传递user和password)
    # connect_db("localhost", 3306, "root", "123456") # TypeError

    # 场景:发送邮件
    def send_email(to, subject, *, cc=None, bcc=None, attachments=None):
    print(f"收件人: {to}")
    print(f"主题: {subject}")
    if cc:
    print(f"抄送: {cc}")
    if attachments:
    print(f"附件: {len(attachments)}个")
    # 发送逻辑

    send_email("admin@example.com", "Hello", cc="boss@example.com", attachments=["a.pdf"])
    send_email("user@example.com", "Meeting") # cc和attachments可选

    # 使用单独的*强制所有后续参数为关键字
    def safe_division(a, b, *, ignore_zero=False):
    if b == 0:
    if ignore_zero:
    return float('inf')
    else:
    raise ValueError("除数不能为零")
    return a / b

    print(safe_division(10, 2)) # 5.0
    print(safe_division(10, 0, ignore_zero=True)) # inf
    # print(safe_division(10, 0, True)) # 错误,True必须用关键字

    案例6:综合实战——灵活的参数设计

    """
    flexible_api.py
    设计一个可以统计数据的函数,支持多种调用方式
    """

    def stats(data, *args, **kwargs):
    """
    统计数据的均值、最大最小值,支持多种输入方式。

    参数:
    data: 可以是列表/元组,或者通过位置参数传入多个数值
    *args: 如果data是单个数值,则将所有位置参数作为数据
    **kwargs:
    – verbose: 是否打印详细信息
    – as_dict: 是否返回字典而非元组
    """
    # 处理数据收集
    if isinstance(data, (list, tuple)):
    numbers = list(data) + list(args)
    else:
    numbers = [data] + list(args)

    if not numbers:
    return None

    total = sum(numbers)
    avg = total / len(numbers)
    max_val = max(numbers)
    min_val = min(numbers)

    verbose = kwargs.get('verbose', False)
    if verbose:
    print(f"数据: {numbers}")
    print(f"个数: {len(numbers)}")
    print(f"总和: {total}")
    print(f"平均: {avg:.2f}")
    print(f"最大: {max_val}")
    print(f"最小: {min_val}")

    if kwargs.get('as_dict', False):
    return {"avg": avg, "max": max_val, "min": min_val, "sum": total, "count": len(numbers)}
    else:
    return avg, max_val, min_val, total, len(numbers)

    # 多种调用方式
    print("=== 调用方式1: 传入列表 ===")
    print(stats([1,2,3,4,5]))
    print("=== 调用方式2: 传入多个数值 ===")
    print(stats(10, 20, 30, 40))
    print("=== 调用方式3: 混合(第一个作为数据,其余作为额外数值)===")
    print(stats(100, 200, 300, verbose=True))
    print("=== 调用方式4: 返回字典 ===")
    result = stats(5,10,15, as_dict=True)
    print(result)


    ⚠️ 易错点避坑总结

    序号坑点描述后果解决方案
    1 默认参数使用可变对象(列表/字典) 多次调用共享同一对象,累积修改 默认参数设为None,内部重新创建
    2 调用时关键字参数在位置参数之前 SyntaxError 所有位置参数必须在前
    3 在同一定义中,默认参数后出现无默认值的参数 SyntaxError 调整顺序,无默认值参数在前
    4 混淆*args在函数定义和调用中的含义 打包/解包概念混淆 定义时:*args打包为元组;调用时:*seq解包序列
    5 忘记*args和**kwargs的名称只是惯例 可读性差 坚持使用args和kwargs
    6 在仅限关键字参数后出现**kwargs 顺序错误 **kwargs必须在最后
    7 尝试使用位置参数传递仅限关键字参数 TypeError 必须使用param=value形式
    8 在函数内部修改全局变量时忘记global 创建了局部变量,不影响全局 明确需要修改时声明global
    9 过度使用*args和**kwargs导致函数签名不清晰 API难以理解 优先使用显式参数,必要时才用可变参数
    10 默认参数的值依赖于可变外部变量 行为不可预测 默认参数值应在定义时确定,避免引用外部可变对象

    📝 课后实战练习题

    第1题:参数顺序练习

    定义以下函数,要求参数按照:位置参数a,默认参数b=10,可变位置参数*args,仅限关键字参数c,可变关键字参数**kwargs。然后调用该函数,传入适当的值,验证顺序。

    第2题:默认参数陷阱修复

    以下代码意图是实现一个缓存字典,但每次调用get_cache都会共享同一个字典。请指出问题并修复。

    def get_cache(key, cache={}):
    if key in cache:
    return cache[key]
    value = f"value_{key}"
    cache[key] = value
    return value

    print(get_cache("a")) # 第一次
    print(get_cache("b")) # 第二次
    print(get_cache("a")) # 应该从缓存获取

    第3题:使用*args实现通用求和

    编写一个函数product(*args),返回所有参数的乘积。如果无参数,返回1。测试product(2,3,4)和product()。

    第4题:关键字参数与仅限关键字参数

    定义函数register(username, password, *, email=None, phone=None),实现用户注册。要求username和password是位置或关键字,email和phone必须用关键字传递。编写调用示例。

    第5题:参数解包练习

    有一个列表data = [5, 10, 15],编写一个函数sum_three(a,b,c)返回三数之和。使用解包方式调用该函数。再有一个字典info = {"name": "张三", "age": 25, "city": "北京"},函数display(name, age, city)打印信息,使用解包调用。

    第6题:设计灵活的函数

    设计一个函数send_message(to, subject, *content_lines, **options),其中content_lines是多行文本,options可以包含cc、bcc、priority等。函数内部打印所有信息。示例调用:

    send_message("admin@example.com", "Hello", "Line1", "Line2", cc="boss@example.com", priority=1)

    第7题:综合应用题——函数参数解析器

    编写一个函数call_with_args(func, args_dict),接收一个函数func和一个字典args_dict,字典的键是参数名,值是要传递的值。使用参数解包调用func,并返回结果。测试如下:

    def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

    args = {"name": "Alice", "greeting": "Hi"}
    print(call_with_args(greet, args)) # 输出 "Hi, Alice!"

    提示:使用**args_dict解包。

    🧠 知识点思维导图总结

    #mermaid-svg-zqj5kbxPzpWqreRH{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zqj5kbxPzpWqreRH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zqj5kbxPzpWqreRH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zqj5kbxPzpWqreRH .error-icon{fill:#552222;}#mermaid-svg-zqj5kbxPzpWqreRH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zqj5kbxPzpWqreRH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zqj5kbxPzpWqreRH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zqj5kbxPzpWqreRH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zqj5kbxPzpWqreRH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zqj5kbxPzpWqreRH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zqj5kbxPzpWqreRH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zqj5kbxPzpWqreRH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zqj5kbxPzpWqreRH .marker.cross{stroke:#333333;}#mermaid-svg-zqj5kbxPzpWqreRH svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zqj5kbxPzpWqreRH p{margin:0;}#mermaid-svg-zqj5kbxPzpWqreRH .edge{stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .section–1 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section–1 path,#mermaid-svg-zqj5kbxPzpWqreRH .section–1 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section–1 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section–1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section–1 text{fill:#ffffff;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon–1{font-size:40px;color:#ffffff;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge–1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth–1{stroke-width:17;}#mermaid-svg-zqj5kbxPzpWqreRH .section–1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-0 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-0 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-0 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-0 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-0 text{fill:black;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-0{font-size:40px;color:black;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-0{stroke-width:14;}#mermaid-svg-zqj5kbxPzpWqreRH .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-1 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-1 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-1 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-1 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-1 text{fill:black;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-1{font-size:40px;color:black;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-1{stroke-width:11;}#mermaid-svg-zqj5kbxPzpWqreRH .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-2 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-2 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-2 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-2 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-2 text{fill:#ffffff;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-2{stroke-width:8;}#mermaid-svg-zqj5kbxPzpWqreRH .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-3 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-3 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-3 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-3 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-3 text{fill:black;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-3{font-size:40px;color:black;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-3{stroke-width:5;}#mermaid-svg-zqj5kbxPzpWqreRH .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-4 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-4 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-4 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-4 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-4 text{fill:black;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-4{font-size:40px;color:black;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-4{stroke-width:2;}#mermaid-svg-zqj5kbxPzpWqreRH .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-5 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-5 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-5 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-5 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-5 text{fill:black;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-5{font-size:40px;color:black;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-5{stroke-width:-1;}#mermaid-svg-zqj5kbxPzpWqreRH .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-6 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-6 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-6 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-6 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-6 text{fill:black;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-6{font-size:40px;color:black;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-6{stroke-width:-4;}#mermaid-svg-zqj5kbxPzpWqreRH .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-7 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-7 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-7 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-7 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-7 text{fill:black;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-7{font-size:40px;color:black;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-7{stroke-width:-7;}#mermaid-svg-zqj5kbxPzpWqreRH .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-8 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-8 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-8 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-8 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-8 text{fill:black;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-8{font-size:40px;color:black;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-8{stroke-width:-10;}#mermaid-svg-zqj5kbxPzpWqreRH .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-9 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-9 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-9 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-9 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-9 text{fill:black;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-9{font-size:40px;color:black;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-9{stroke-width:-13;}#mermaid-svg-zqj5kbxPzpWqreRH .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-10 rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-10 path,#mermaid-svg-zqj5kbxPzpWqreRH .section-10 circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-10 polygon,#mermaid-svg-zqj5kbxPzpWqreRH .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-10 text{fill:black;}#mermaid-svg-zqj5kbxPzpWqreRH .node-icon-10{font-size:40px;color:black;}#mermaid-svg-zqj5kbxPzpWqreRH .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .edge-depth-10{stroke-width:-16;}#mermaid-svg-zqj5kbxPzpWqreRH .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled,#mermaid-svg-zqj5kbxPzpWqreRH .disabled circle,#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:lightgray;}#mermaid-svg-zqj5kbxPzpWqreRH .disabled text{fill:#efefef;}#mermaid-svg-zqj5kbxPzpWqreRH .section-root rect,#mermaid-svg-zqj5kbxPzpWqreRH .section-root path,#mermaid-svg-zqj5kbxPzpWqreRH .section-root circle,#mermaid-svg-zqj5kbxPzpWqreRH .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-zqj5kbxPzpWqreRH .section-root text{fill:#ffffff;}#mermaid-svg-zqj5kbxPzpWqreRH .section-root span{color:#ffffff;}#mermaid-svg-zqj5kbxPzpWqreRH .section-2 span{color:#ffffff;}#mermaid-svg-zqj5kbxPzpWqreRH .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-zqj5kbxPzpWqreRH .edge{fill:none;}#mermaid-svg-zqj5kbxPzpWqreRH .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-zqj5kbxPzpWqreRH :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    第12课:函数参数进阶

    参数分类

    位置参数

    关键字参数

    默认参数

    可变默认参数的陷阱

    None哨兵解决方案

    可变位置参数 *args

    可变关键字参数 **kwargs

    仅限关键字参数

    在*args之后

    在单独的*之后

    参数顺序

    位置参数 → 默认参数 → *args → 仅限关键字 → **kwargs

    参数解包(调用时)

    解包序列 *seq

    解包字典 **dict

    面试考点

    *args和**kwargs作用

    默认参数求值时机

    仅限关键字参数定义

    可变默认参数危害

    实战应用

    通用装饰器

    灵活API设计

    配置参数传递


    🔜 下节课预告

    参数是函数的输入,但函数内部变量的作用范围和生命周期同样重要。下一节课我们将深入讨论作用域,包括局部变量、全局变量、闭包等进阶概念。

    第13课:局部变量、全局变量、函数作用域与闭包基础精讲

    内容包括:

    • 全局变量和局部变量的访问与修改
    • global和nonlocal关键字
    • LEGB作用域查找规则
    • 闭包的基础概念
    • 实战:计数器、配置管理

    理解作用域是掌握Python高级特性的关键一步,为后续的装饰器和面向对象打基础。

    🌟 学习鼓励:函数的参数体系是Python灵活性的重要体现。看似复杂的规则,只要记住“定义时的顺序规则”和“调用时的位置在前、关键字在后”,再配合练习,很快就能掌握。请务必亲手运行每个案例,修改参数观察现象,你会发现参数设计的精妙之处。


    🔗《50节课 Python 从入门到精通》系列课程导航

    去订阅

    🌟 感谢您耐心阅读到这里! 💡 如果本文对您有所启发欢迎: 👍 点赞📌 收藏 📤 分享给更多需要的伙伴。 🗣️ 期待在评论区看到您的想法, 共同进步。 🔔 关注我,持续获取更多干货内容~ 🤗 我们下篇文章见~

    赞(0)
    未经允许不得转载:171主机测评 » 第12课:Python|函数进阶【位置参数、关键字参数、默认参数、不定长参数全解】
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址