Python函数
·


1. 🎁 函数是什么
想象一下,函数就像一个自动咖啡机☕:
- 你放入咖啡豆和水(输入)
- 机器按照固定步骤制作(处理过程)
- 最后给你一杯香浓的咖啡(输出)
# 函数就是一段可以重复使用的代码
def make_coffee(beans, water):
# 制作咖啡的过程
coffee = beans + water + "搅拌搅拌"
return coffee
# 每次想喝咖啡,只需要调用函数
my_coffee = make_coffee("阿拉比卡豆", "纯净水")
2. 📝 语法格式
def 函数名(参数1, 参数2, ...):
"""函数说明文档(可选)"""
函数体(具体要做的事)
return 返回值(可选)
记住口诀:def开头,冒号结尾,缩进很重要!😊
# 完整示例
def calculate_area(length, width):
"""计算矩形面积"""
area = length * width
return area
# 调用函数
result = calculate_area(5, 3) # result = 15
3. 📦 函数参数
函数参数就像外卖订单🍔 - 你要告诉店家你想要什么!
3.1 位置参数(必须按顺序)
def introduce(name, age, city):
print(f"我叫{name},今年{age}岁,来自{city}")
introduce("小明", 18, "北京") # ✅ 正确
# introduce(18, "小明", "北京") # ❌ 顺序错了会出问题!
3.2 默认参数(有默认值)
def order_coffee(size="中杯", sugar="少糖"):
print(f"您点了{size},{sugar}的咖啡")
order_coffee() # 中杯,少糖的咖啡
order_coffee("大杯") # 大杯,少糖的咖啡
order_coffee("大杯", "无糖") # 大杯,无糖的咖啡
3.3 关键字参数(指定参数名)
def create_profile(name, age, hobby):
print(f"{name},{age}岁,爱好是{hobby}")
# 使用关键字参数,顺序可以随意!
create_profile(age=25, hobby="编程", name="小红") # ✅
create_profile(name="小刚", hobby="游泳", age=30) # ✅
3.4 可变参数(*args 和 **kwargs)
# *args:接收任意数量的位置参数
def eat_food(*foods):
print("今天吃了:")
for food in foods:
print(f"- {food}")
eat_food("汉堡", "薯条", "可乐", "冰淇淋") # 想吃多少写多少!
# **kwargs:接收任意数量的关键字参数
def print_info(**info):
for key, value in info.items():
print(f"{key}: {value}")
print_info(name="小明", age=18, city="上海", hobby="打篮球")
4. 🎯 函数返回值
📦 知识点一:返回单个值
核心说明:函数通过 return 返回单一计算结果
def add(a, b):
return a + b # 用return返回计算结果
result = add(3, 5) # 接收返回值
print(result) # 输出: 8
关键点:
return是函数输出结果的唯一方式- 返回值可直接使用或存入变量
📬 知识点二:返回多个值(元组解包)
核心说明:函数可返回元组,通过解包获取多个值
def get_min_max(numbers):
return min(numbers), max(numbers) # 返回元组
# 解包接收多个返回值
minimum, maximum = get_min_max([1, 5, 3, 9, 2])
print(f"最小值:{minimum},最大值:{maximum}") # 输出: 最小值:1,最大值:9
关键点:
- 多返回值本质是返回元组
(min, max)- 解包语法
a, b = func()可同时获取多个值
🚫 知识点三:无返回值行为(None)
核心说明:函数无return时默认返回None
def say_hello():
print("Hello!") # 只有输出语句
# 无return语句
result = say_hello() # 调用函数(输出Hello!)
print(result) # 输出: None
5. 🏠 变量作用域
📢 知识点一:全局变量(全校可见)
核心:全局变量全局可见
school_motto = "勤奋 诚信 创新" # 全局变量(全校公告)
def classroom_301():
print(school_motto) # ✅ 任何教室都能看到校训
classroom_301() # 输出:勤奋 诚信 创新
🚪 知识点二:局部变量(仅本班可用)
核心:函数内变量只在本函数内有效
def classroom_301():
class_secret = "明天有惊喜测验" # 局部变量(班级秘密)
print(class_secret) # ✅ 本班同学知道
# print(class_secret) # ❌ 其他班级无法知道
📚 知识点三:嵌套作用域(小组在班级内)
核心:
- 内层函数可访问外层变量
- 外层不能访问内层变量
def classroom_301():
class_secret = "明天有惊喜测验"
def study_group():
group_plan = "放学后补习数学" # 小组内部变量
print(class_secret) # ✅ 小组知道班级秘密
study_group() # 成功输出班级秘密
# print(group_plan) # ❌ 班级不知道小组计划
LEGB规则(查找顺序)
- Local(局部)→ Enclosing(外层函数)→ Global(全局)→ Built-in(内置)
x = "全局变量"
def outer():
x = "外层函数变量"
def inner():
x = "局部变量"
print(x) # 输出:局部变量
inner()
print(x) # 输出:外层函数变量
outer()
print(x) # 输出:全局变量
6. 🎬 函数执行过程
函数就像一个小型工厂:你提供原材料(参数),它按照固定流程加工,最后给你成品(返回值)。
核心概念:
- 传入参数:调用函数时传递数据
- 执行步骤:按顺序运行函数内代码
- 返回结果:通过
return输出最终产品 - 清理现场:函数结束后,内部变量自动清除
🍰 蛋糕工厂示例
def cake_factory(flavor):
# 1. 接收原材料
print(f"收到原料:{flavor}")
# 2. 加工步骤
mix = f"搅拌{flavor}面糊"
bake = "烘烤20分钟"
print(mix)
print(bake)
# 3. 产出成品
cake = f"★{flavor}蛋糕★"
return cake
# 使用工厂
order = "巧克力" # 下单原料
product = cake_factory(order) # 工厂加工
print(f"收到成品:{product}")
# 尝试访问工厂内部(会失败)
# print(mix) # 错误!工厂内部变量已清除
关键理解:
- 函数像临时工厂:接收原料→加工→产出→清理
return是交货时刻,之后工厂立即关闭- 内部变量如
mix是临时工具,外部无法访问- 整个过程按代码顺序一步步执行
7. 🔗 链式调用
链式调用就像工厂的流水线作业:前一道工序的输出直接成为下一道工序的输入,形成连续的处理流程
判定是否是奇数
def isOdd(num):
if num % 2 == 0:
return False
else:
return True
实际上也可以简化写作
print(isOdd(10))
8. 🎪 嵌套调用
核心概念: 嵌套调用就像俄罗斯套娃:在一个函数的执行过程中,又调用了其他函数,形成层层嵌套的执行结构
🌐 多层嵌套示例
def get_user():
return "Alice"
def greet(user):
return f"Hello, {user}!"
def display(greeting):
print(greeting + " 👋")
# 三层嵌套调用
display(greet(get_user())) # 输出: Hello, Alice! 👋
执行顺序:
- 最内层:
get_user()→ 返回"Alice" - 中间层:
greet("Alice")→ 返回"Hello, Alice!" - 最外层:
display("Hello, Alice!")→ 打印结果
💡 嵌套调用最佳实践
- 层次限制:嵌套不宜过深(建议≤3层)
- 功能单一:每个函数只做一件事
- 清晰命名:函数名明确表达功能
- 错误处理:内层函数应有异常处理
9. 🔄 函数递归
递归就像镜子中的镜子:函数在执行过程中调用自身,将大问题分解成相似的小问题,直到达到最简单的情况。
核心概念:
- 自调用:函数内部直接或间接调用自身
- 问题分解:将复杂问题分解为相同结构的子问题
- 基准条件:存在明确的终止条件(递归出口)
- 堆栈机制:每次调用创建新的栈帧,后进先出(LIFO)
🧮 阶乘计算示例
def factorial(n):
# 基准条件:0! = 1
if n == 0:
return 1
# 递归步骤:n! = n * (n-1)!
else:
return n * factorial(n-1)
print(factorial(3)) # 输出: 6 (3×2×1=6)
执行过程解析(计算 factorial(3)):
1. factorial(3) = 3 × factorial(2) → 等待factorial(2)结果
2. factorial(2) = 2 × factorial(1) → 等待factorial(1)结果
3. factorial(1) = 1 × factorial(0) → 等待factorial(0)结果
4. factorial(0) = 1 (基准条件)
5. factorial(1) = 1 × 1 = 1
6. factorial(2) = 2 × 1 = 2
7. factorial(3) = 3 × 2 = 6
⚠️ 递归使用要点
| 要点 | 说明 | 示例 |
|---|---|---|
| 必须的基准条件 | 防止无限递归 | if n==0: return 1 |
| 问题规模递减 | 每次递归问题应更小 | factorial(n-1) |
| 堆栈深度限制 | Python默认约1000层 | sys.setrecursionlimit(1500) |
| 尾递归优化 | Python不支持,需手动转循环 | 使用循环替代深层递归 |
🔄 递归 vs 循环
| 特性 | 递归 | 循环 |
|---|---|---|
| 代码简洁性 | ★★★ 更简洁 | ★★ 稍繁琐 |
| 内存消耗 | ★ 栈空间消耗大 | ★★★ 内存高效 |
| 可读性 | ★★ 结构性问题更直观 | ★★★ 简单问题更直接 |
| 适用场景 | 树结构、分治算法 | 线性迭代、性能敏感 |
关键理解:
- 递归是
分而治之的策略,将问题分解为相似子问题- 基准条件是递归的
安全阀,必不可少- 递归调用形成调用栈,深度过大导致栈溢出
- 适合处理嵌套结构(文件系统、语法树、组合问题)
参数默认值就像餐厅的套餐默认配置:点餐时如果没特别说明,就按默认方案提供,但顾客可以随时自定义。
核心概念:
- 预设值:定义函数时给参数指定默认值
- 可选参数:调用时可省略有默认值的参数
- 位置约束:默认参数必须放在非默认参数后面
- 默认值计算:默认值在函数定义时确定(仅一次)
10. 🎯 参数默认值
🍔 餐厅点餐示例
def order_food(dish, drink="可乐", side="薯条"):
"""点餐函数:主菜必选,饮料和配菜可选"""
print(f"🍽️ 您点了:{dish} + {drink} + {side}")
# 使用默认配置
order_food("汉堡") # 输出:🍽️ 您点了:汉堡 + 可乐 + 薯条
# 自定义部分配置
order_food("炸鸡", "雪碧") # 输出:🍽️ 您点了:炸鸡 + 雪碧 + 薯条
# 完全自定义
order_food("披萨", "柠檬茶", "沙拉") # 输出:🍽️ 您点了:披萨 + 柠檬茶 + 沙拉
⚠️ 重要注意事项
1️⃣ 默认值只初始化一次(对可变对象需谨慎)
def add_item(item, cart=[]): # 默认值为可变对象(列表)
cart.append(item)
return cart
# 第一次调用正常
print(add_item("苹果")) # ['苹果']
# 第二次调用会保留上次结果(通常不是预期行为)
print(add_item("香蕉")) # ['苹果', '香蕉'] ❌
正确做法:使用None作为占位符
def add_item(item, cart=None):
if cart is None: # 每次调用创建新列表
cart = []
cart.append(item)
return cart
print(add_item("苹果")) # ['苹果']
print(add_item("香蕉")) # ['香蕉'] ✅
2️⃣ 默认参数必须放在最后
# 正确写法
def func(a, b=1, c=2):
pass
# 错误写法(会报错)
def func(a=1, b, c):
pass
🆚 默认参数 vs 必需参数
| 特性 | 默认参数 | 必需参数 |
|---|---|---|
| 定义方式 | param=default_value |
无默认值 |
| 调用要求 | 可省略 | 必须提供 |
| 位置 | 必须在非默认参数后 | 可在任意位置 |
| 典型用途 | 可选配置项 | 核心输入数据 |
11. 🏷️ 关键字参数
关键字参数就像快递包裹上的标签:通过明确的参数名指定值,不再依赖顺序,让函数调用更清晰灵活。
核心概念:
- 按名传递:调用时使用
参数名=值的形式 - 顺序无关:参数顺序可以任意调整
- 可读性强:明确显示每个参数的作用
- 结合位置参数:位置参数在前,关键字参数在后
def test(x, y):
print(f'x = {x}')
print(f'y = {y}')
test(x=10, y=20)
test(y=100, x=200)
形如上述
test(x=10, y=20)这样的操作, 即为 关键字参数.
🎯 综合练习时间!
现在来个小挑战,测试你是否真的理解了:
题目:写一个函数calculate_grade(score, bonus=0)
- 计算最终成绩(分数+奖励分)
- 如果最终成绩>=90,返回"优秀"
- 如果最终成绩>=80,返回"良好"
- 如果最终成绩>=60,返回"及格"
- 否则返回"不及格"
美图分享

🌟💖📌➕👀 点赞收藏加关注,学习知识不迷路 🌟
🎊✅🚀🎊✅🚀🎊✅🚀🎊✅🚀🎊
👍🔥🚩点赞☀️收藏🌟关注🔥👍
👍🔥🚩点赞☀️收藏🌟关注🔥👍
👍🔥🚩点赞☀️收藏🌟关注🔥👍
💫💫💫💫💫💫💫💫💫💫💫💫💫
更多推荐


所有评论(0)