📚 今日学习目标
掌握 Python 函数的核心概念,理解参数传递的多种方式,能够编写可复用的函数代码。
一、什么是函数?
函数是组织好的、可重复使用的代码块,用于实现单一或相关联的功能。Python 提供了许多内置函数(如 print()、len()),同时也允许我们自定义函数。
函数的优势
- 代码复用:一次定义,多次调用
- 模块化:将复杂问题分解为小问题
- 可维护性:修改一处,全局生效
- 可读性:通过函数名表达意图
二、函数的定义与调用
基本语法
def function_name(parameters):
"""文档字符串:描述函数功能"""
# 函数体
return result # 可选
示例:简单的问候函数
def greet(name, greeting="你好"):
"""向指定的人发送问候"""
message = f"{greeting},{name}!"
return message
# 调用函数
print(greet("小明")) # 输出:你好,小明!
print(greet("Alice", "Hello")) # 输出:Hello,Alice!
三、参数的五种类型
1. 位置参数
按参数位置传递,顺序必须匹配:
def calculate_area(width, height):
"""计算矩形面积"""
return width * height
# 位置参数调用
area = calculate_area(5, 3) # width=5, height=3
print(f"面积:{area}") # 输出:面积:15
2. 默认参数
为参数提供默认值,调用时可省略:
def create_user(username, role="user", active=True):
"""创建用户信息"""
return {
"username": username,
"role": role,
"active": active
}
# 使用默认参数
user1 = create_user("zhangsan")
print(user1) # {'username': 'zhangsan', 'role': 'user', 'active': True}
# 覆盖默认参数
user2 = create_user("admin", role="admin", active=True)
print(user2) # {'username': 'admin', 'role': 'admin', 'active': True}
3. 关键字参数
通过参数名传递,顺序可以打乱:
def describe_pet(pet_name, animal_type="dog"):
"""描述宠物信息"""
print(f"我有一只{animal_type},它叫{pet_name}")
# 关键字参数调用
describe_pet(animal_type="cat", pet_name="咪咪")
# 输出:我有一只 cat,它叫咪咪
4. 可变位置参数 (*args)
接收任意数量的位置参数,打包为元组:
def sum_all(*numbers):
"""计算任意数量数字的和"""
total = 0
for num in numbers:
total += num
return total
print(sum_all(1, 2, 3)) # 输出:6
print(sum_all(1, 2, 3, 4, 5)) # 输出:15
print(sum_all()) # 输出:0
5. 可变关键字参数 (**kwargs)
接收任意数量的关键字参数,打包为字典:
def build_profile(first_name, last_name, **info):
"""构建用户档案"""
profile = {
"first_name": first_name,
"last_name": last_name
}
profile.update(info)
return profile
user = build_profile(
"John",
"Doe",
age=30,
city="Beijing",
occupation="Engineer"
)
print(user)
# 输出:{'first_name': 'John', 'last_name': 'Doe', 'age': 30, 'city': 'Beijing', 'occupation': 'Engineer'}
四、参数传递的顺序规则
当混合使用多种参数类型时,必须遵循以下顺序:
def complex_function(pos1, pos2, default1="A", default2="B", *args, **kwargs):
"""
参数顺序:
1. 位置参数 (pos1, pos2)
2. 默认参数 (default1, default2)
3. 可变位置参数 (*args)
4. 可变关键字参数 (**kwargs)
"""
print(f"位置参数:{pos1}, {pos2}")
print(f"默认参数:{default1}, {default2}")
print(f"可变位置:{args}")
print(f"可变关键字:{kwargs}")
# 调用示例
complex_function(1, 2, "X", "Y", 10, 20, 30, key1="value1", key2="value2")
五、返回值与多重返回
单一返回值
def square(x):
"""计算平方"""
return x * x
result = square(5)
print(result) # 输出:25
多重返回值(实际返回元组)
def get_user_stats(users):
"""统计用户列表的最大值、最小值和平均值"""
if not users:
return None, None, None
max_val = max(users)
min_val = min(users)
avg_val = sum(users) / len(users)
return max_val, min_val, avg_val
# 解包返回值
scores = [85, 92, 78, 96, 88]
maximum, minimum, average = get_user_stats(scores)
print(f"最高分:{maximum}, 最低分:{minimum}, 平均分:{average:.2f}")
# 输出:最高分:96, 最低分:78, 平均分:87.80
六、变量作用域
局部变量 vs 全局变量
global_var = "我是全局变量"
def test_scope():
local_var = "我是局部变量"
print(f"函数内访问全局:{global_var}")
print(f"函数内访问局部:{local_var}")
test_scope()
# print(local_var) # ❌ 错误:局部变量在函数外不可访问
使用 global 修改全局变量
counter = 0
def increment():
global counter
counter += 1
return counter
print(increment()) # 输出:1
print(increment()) # 输出:2
print(increment()) # 输出:3
七、实战案例:计算器函数
def calculator(a, b, operation="+"):
"""
简易计算器
参数:
a: 第一个操作数
b: 第二个操作数
operation: 运算符 (+, -, *, /, //, %, **)
返回:
计算结果或错误信息
"""
operations = {
"+": lambda x, y: x + y,
"-": lambda x, y: x - y,
"*": lambda x, y: x * y,
"/": lambda x, y: x / y if y != 0 else "错误:除数不能为零",
"//": lambda x, y: x // y if y != 0 else "错误:除数不能为零",
"%": lambda x, y: x % y if y != 0 else "错误:除数不能为零",
"**": lambda x, y: x ** y
}
if operation not in operations:
return f"错误:不支持的运算符 '{operation}'"
result = operations[operation](a, b)
return result
# 测试计算器
print(calculator(10, 5, "+")) # 输出:15
print(calculator(10, 5, "*")) # 输出:50
print(calculator(10, 0, "/")) # 输出:错误:除数不能为零
print(calculator(2, 3, "**")) # 输出:8
八、最佳实践建议
- 函数命名:使用小写字母和下划线,如
calculate_total - 单一职责:一个函数只做一件事
- 文档字符串:始终添加 docstring 说明功能
- 参数默认值:谨慎使用可变对象作为默认值
- 类型提示:Python 3.5+ 推荐使用类型注解
from typing import List, Optional
def find_max(numbers: List[int]) -> Optional[int]:
"""查找列表中的最大值"""
if not numbers:
return None
return max(numbers)
📝 今日总结
| 知识点 | 关键内容 |
|---|---|
| 函数定义 | def 关键字 + 函数名 + 参数 |
| 参数类型 | 位置、默认、关键字、*args、**kwargs |
| 返回值 | return 语句,可返回多个值 |
| 作用域 | 局部变量 vs 全局变量 |
| 最佳实践 | 命名规范、单一职责、文档字符串 |