
文章目录
- 📖 开篇导读
- 🎯 学习目标
- 📚 知识点理论精讲
-
- 一、回顾与深入:位置参数与关键字参数
-
- 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)。
六、参数组合的完整顺序
在函数定义中,所有参数必须遵循以下顺序:
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 从入门到精通》系列课程导航
去订阅
🌟 感谢您耐心阅读到这里! 💡 如果本文对您有所启发欢迎: 👍 点赞📌 收藏 📤 分享给更多需要的伙伴。 🗣️ 期待在评论区看到您的想法, 共同进步。 🔔 关注我,持续获取更多干货内容~ 🤗 我们下篇文章见~




