Python: 函数基础
到现在为止,你写的代码都是一行接一行执行。但如果同样的功能要重复用呢?每次都复制粘贴?函数就是来解决这个问题的——把一段代码打包,起个名字,想用就调用它。这是"从写代码到组织代码"的第一步。
1. 什么是函数
函数就是一段有名字的代码块,你可以随时调用它。
PYTHON
# 定义函数
def say_hello():
print("你好!")
print("欢迎学习 Python!")
# 调用函数
say_hello()
say_hello() # 可以反复调用
运行结果:
TEXT
📖 仅展示
你好!
欢迎学习 Python!
你好!
欢迎学习 Python!
💡 为什么用函数? ① 避免重复代码(DRY=Don't Repeat Yourself)。② 代码更容易理解——一个好函数名比一大段注释有用。③ 修改时只改一处,所有调用自动更新。
2. 参数:给函数传数据
函数可以接收参数,让函数更灵活:
PYTHON
def greet(name):
"""向指定的名字打招呼"""
print(f"你好,{name}!欢迎来到 Python 世界。")
greet("Alice") # 你好,Alice!欢迎来到 Python 世界。
greet("Bob") # 你好,Bob!欢迎来到 Python 世界。
(1) 多个参数
PYTHON
def introduce(name, age, city):
print(f"我叫{name},今年{age}岁,来自{city}。")
introduce("Alice", 25, "北京")
introduce("Bob", 30, "上海")
(2) 参数顺序:位置参数
调用函数时传入的参数按顺序匹配:
PYTHON
def create_user(name, age, is_admin):
print(f"创建用户:{name},年龄:{age},管理员:{is_admin}")
create_user("Alice", 25, False) # 按顺序匹配
create_user(False, "Alice", 25) # ❌ 顺序错了——is_admin 被赋值为 False 但位置不对
▶ 示例:计算器函数(难度⭐)
PYTHON
def add(a, b):
print(f"{a} + {b} = {a + b}")
def multiply(a, b):
print(f"{a} × {b} = {a * b}")
add(5, 3) # 5 + 3 = 8
multiply(5, 3) # 5 × 3 = 15
输出:
TEXT
📖 仅展示
# 函数定义成功
3. 返回值
函数可以用 return 返回一个结果给调用方:
PYTHON
def add(a, b):
return a + b
result = add(5, 3)
print(result) # 8
# 返回值可以直接用在表达式中
total = add(10, 20) + add(30, 40)
print(total) # 100
⚠️ 如果函数没有
return,它返回 None。这和"没有返回值"是两回事——它确实返回了,只不过返回的是 None。
(1) 多个返回值
Python 可以一次返回多个值(本质是返回元组):
PYTHON
def get_min_max(numbers):
return min(numbers), max(numbers)
result = get_min_max([3, 1, 4, 1, 5])
print(result) # (1, 5)
# 直接用解包接收
low, high = get_min_max([3, 1, 4, 1, 5])
print(f"最小值:{low},最大值:{high}")
(2) return 的作用
return 会立即结束函数的执行,后面的代码不会运行:
PYTHON
def check_age(age):
if age < 0:
return "年龄不能为负数!" # 提前返回
if age < 18:
return "未成年"
return "已成年"
print(check_age(-5)) # 年龄不能为负数!
print(check_age(15)) # 未成年
print(check_age(25)) # 已成年
▶ 示例:温度转换工具(难度⭐⭐)
PYTHON
def celsius_to_fahrenheit(c):
"""摄氏温度转华氏温度"""
return c * 9 / 5 + 32
def fahrenheit_to_celsius(f):
"""华氏温度转摄氏温度"""
return (f - 32) * 5 / 9
# 测试
print(f"0°C = {celsius_to_fahrenheit(0):.1f}°F") # 32.0°F
print(f"100°C = {celsius_to_fahrenheit(100):.1f}°F") # 212.0°F
print(f"32°F = {fahrenheit_to_celsius(32):.1f}°C") # 0.0°C
print(f"212°F = {fahrenheit_to_celsius(212):.1f}°C") # 100.0°C
输出:
TEXT
📖 仅展示
# 函数定义成功
▶ 示例:带默认参数的问候函数(难度⭐)
PYTHON
def greet(name, greeting="你好", punctuation="!"):
"""生成问候语
参数:
name: 被问候的人名
greeting: 问候词,默认"你好"
punctuation: 结尾标点,默认"!"
"""
return f"{greeting},{name}{punctuation}"
# 使用默认参数
print(greet("Alice"))
print(greet("Bob"))
# 覆盖部分默认参数
print(greet("Charlie", greeting="早上好"))
print(greet("Diana", greeting="晚安", punctuation="~"))
# 混合位置参数和关键字参数
def build_profile(name, age, city="未知", hobby="编程"):
"""构建个人简介"""
return f"{name},{age}岁,来自{city},喜欢{hobby}"
print(build_profile("Alice", 25))
print(build_profile("Bob", 30, city="上海"))
print(build_profile("Charlie", 22, city="北京", hobby="绘画"))
输出:
TEXT
📖 仅展示
你好,Alice!
你好,Bob!
早上好,Charlie!
晚安,Diana~
Alice,25岁,来自未知,喜欢编程
Bob,30岁,来自上海,喜欢编程
Charlie,22岁,来自北京,喜欢绘画
4. 文档字符串 docstring
函数定义后第一行用 """ 写的注释就是文档字符串,用于说明函数的作用:
PYTHON
def calculate_bmi(weight, height):
"""
计算 BMI 身体质量指数
参数:
weight (float): 体重,单位 kg
height (float): 身高,单位 m
返回:
float: BMI 值
"""
return weight / (height ** 2)
# 查看文档字符串
print(calculate_bmi.__doc__)
help(calculate_bmi)
💡 好习惯: 写函数时顺手写 docstring,哪怕只有一行。你不写的话:①
help(your_function) 看不到说明;② 过两个月的你自己也搞不清这个函数是干什么的。docstring 的格式不强制,但推荐写上参数说明和返回值说明。
5. 函数调用栈
当函数调用另一个函数时,Python 会在内存中维护一个"调用栈":
PYTHON
def a():
print("进入 a")
b()
print("离开 a")
def b():
print("进入 b")
c()
print("离开 b")
def c():
print("进入 c")
print("离开 c")
a()
运行结果:
TEXT
📖 仅展示
进入 a
进入 b
进入 c
离开 c
离开 b
离开 a
就像一摞盘子——后放上去的先拿走。这个"后进先出"的结构就是栈(stack)。函数嵌套调用太深会导致"栈溢出"(比如递归没有终止条件)。
6. 常见应用场景
- 代码复用:重复出现的逻辑提取成函数,一处定义多处调用。
- 模块化编程:每个函数只做一件事(单一职责),方便测试和维护。
- 计算逻辑封装:数学公式、数据转换、格式校验等封装成函数。
- 流程控制:用多返回值函数处理多种情况(错误、空值、正常结果)。
❓ 常见问题
Q
return 和 print() 有什么区别?A
return 是"把结果交还给调用方",print() 只是"在控制台上显示"。函数必须有 return 才能把值传出去。用 print() 只能看到,用不了。Q 一个函数可以有多个
return 吗?A 可以。函数中可以有多个
return,但只会执行其中一个——第一个遇到的 return 会立即结束函数。这在条件判断中很常用:不同条件返回不同值。Q 函数一定要有参数吗?
A 不一定。没有参数的函数也是完全合法的。比如
def get_current_time(): 不需要任何参数,直接返回当前时间(用 datetime 模块)。参数的数量取决于函数是否需要外部数据。📖 小节
- 函数用
def定义,把代码打包成名可复用的块 - 参数让函数更灵活,按位置依次匹配
return返回结果并结束函数,多返回值本质是元组- 没有
return的函数返回None - docstring 用
"""写函数说明,通过help()查看 - 函数调用栈是后进先出的结构,嵌套调用太深会栈溢出
📝 作业
-
基础题(难度⭐):写一个函数
is_even(n),接收一个整数,返回True如果是偶数,否则返回False。用%运算符。 -
进阶题(难度⭐⭐):写一个函数
grade(score),接收一个分数(0-100),返回对应的等级:90以上返回"A"、80-89返回"B"、70-79返回"C"、60-69返回"D"、60以下返回"F"。用 if-elif 实现。 -
挑战题(难度⭐⭐⭐):写三个函数
add()、subtract()、multiply(),然后写第四个函数calculate(a, b, operator),它接收两个数字和一个运算符字符串("+"、"-"、"*"),调用对应的函数并返回结果。如果运算符不在支持范围内,返回None。