零基础学 Python 第9章 | 函数基础:def、参数与返回值
本章摘要
- 核心目标:学会用
def定义函数,把代码打包成可复用的工具 - 核心知识点:
def定义函数、形参与实参、return返回值、多返回值、函数调用流程、参数默认值 - 实操产出:封装温度转换、BMI计算、密码强度检测三个实用函数工具集
- 前置基础:第8章字符串格式化、第3章
if条件判断、变量与数据类型
一、写在前面
上一章我们学了字符串的各种操作——拼接、格式化、切片、常用方法。你有没有发现一个问题:前面写的所有代码,都是一条一条堆在一起的,从上往下依次执行。
这在简单程序里没问题,但想象一下:你写了一段 20 行的成绩判定逻辑,今天要用,明天还要用,换个班级又要用。你是每次都复制粘贴这 20 行吗?万一逻辑要改,你改一处还是改十处?
函数就是解决这个问题的。把一段代码"打包"起来,起个名字,以后只要喊这个名字,整段代码就会运行。就像家里买了个微波炉——你不用每次都从头造一个,只要按一下按钮,它就帮你加热。
本章是第三部分(函数篇)的第一章。从这里开始,你的代码将从"堆指令"进化为"造工具"。
二、什么是函数
一句话:函数就是给一段代码起个名字,需要时调用这个名字就能执行那段代码。
你其实已经用过函数了。print()、input()、len()——这些都是 Python 内置的函数,别人帮你打包好的,你直接用就行。
现在你要学的是:自己造函数。
函数有三个核心要素:
| 要素 | 说明 | 类比 |
|---|---|---|
| 输入(参数) | 函数需要的数据 | 微波炉里放的食物 |
| 处理(函数体) | 函数内部执行的代码 | 微波炉加热的过程 |
| 输出(返回值) | 函数执行完给出的结果 | 加热好的食物 |
不是所有函数都有输入和输出,但每个函数都有函数体(要执行的代码)。
三、用 def 定义函数
定义函数的关键字是 def,格式如下:
def 函数名():
函数体(要执行的代码)
来写第一个属于自己的函数:
def greet():
print("你好,欢迎学习Python!")
# 调用函数
greet()
运行结果:
你好,欢迎学习Python!
定义了不会自动执行。def 只是"告诉" Python 有这么一个函数,只有调用它(写一次函数名加括号 greet()),里面的代码才会运行。
你可以调用多次:
def greet():
print("你好,欢迎学习Python!")
greet() # 第1次调用
greet() # 第2次调用
greet() # 第3次调用
运行结果:
你好,欢迎学习Python!
你好,欢迎学习Python!
你好,欢迎学习Python!
注意:函数定义必须写在调用之前。Python 从上往下读代码,如果先调用再定义,会报"找不到这个函数"的错误。
四、形参与实参:让函数接收数据
4.1 为什么要传参数
上面的 greet() 每次打印的内容都一样。如果我想对小明说"你好",对小红也说"你好",但名字不同呢?总不能为每个人写一个函数。
参数就是让函数接收外部数据,同一个函数处理不同的输入。
4.2 定义带参数的函数
def greet(name):
print(f"你好,{name}!欢迎学习Python!")
greet("小明")
greet("小红")
运行结果:
你好,小明!欢迎学习Python!
你好,小红!欢迎学习Python!
4.3 形参 vs 实参
这两个术语新手容易混,但其实很简单:
| 术语 | 位置 | 作用 | 例子 |
|---|---|---|---|
| 形参(形式参数) | 函数定义时的括号里 | 占位符,表示"这里需要一个数据" | def greet(name) 中的 name |
| 实参(实际参数) | 调用函数时的括号里 | 真正传入的具体数据 | greet("小明") 中的 "小明" |
一句话记:定义时写形参,调用时传实参。形参是个变量名,实参是具体值,调用时实参会赋值给形参。
4.4 多个参数
函数可以有多个参数,用逗号隔开:
def introduce(name, age, city):
print(f"我叫{name},今年{age}岁,来自{city}")
introduce("小明", 18, "北京")
运行结果:
我叫小明,今年18岁,来自北京
参数的顺序很重要。调用时实参会按顺序一一对应:第一个实参给第一个形参,第二个给第二个……所以
"小明"对应name,18对应age,"北京"对应city。
五、return 返回值:让函数给出结果
5.1 print 和 return 的区别
这是新手最容易搞混的地方。
print()—— 把结果显示到屏幕上,但程序内部拿不到这个值return—— 把结果交还给调用处,程序内部可以继续使用
看个例子:
# 用 print:只显示,拿不到结果
def add_print(a, b):
print(a + b)
# 用 return:把结果交还,可以继续用
def add_return(a, b):
return a + b
# 调用对比
add_print(3, 5) # 屏幕显示 8
result = add_return(3, 5) # result 拿到了 8
print(result) # 屏幕显示 8
print(result * 2) # 屏幕显示 16,能继续用
运行结果:
8
8
16
结论:需要拿到函数的结果继续用,就用 return;只是想显示一下,用 print 就行。 实际开发中,绝大多数函数用 return。
5.2 return 的特点
def check_age(age):
if age >= 18:
return "成年"
return "未成年"
result = check_age(20)
print(result) # 成年
return 有两个作用:
- 返回一个值给调用处
- 立即结束函数——
return之后的代码不会执行
def test():
print("第1行")
return "结束了"
print("第2行") # 这行永远不会执行
print(test())
运行结果:
第1行
结束了
5.3 没有 return 的函数
如果函数里没写 return,Python 会自动返回 None(空值):
def say_hello():
print("你好")
result = say_hello()
print(result) # None
运行结果:
你好
None
None表示"什么都没有"。函数不写return就等于return None,这是 Python 的默认行为。
六、多返回值:一次返回多个结果
Python 有个很方便的特性:函数可以一次返回多个值,用逗号隔开。
def get_score_info(name, chinese, math):
total = chinese + math
average = total / 2
return name, total, average
# 接收时也用逗号隔开,一一对应
name, total, avg = get_score_info("小明", 85, 90)
print(f"{name}:总分{total},平均分{avg}")
运行结果:
小明:总分175,平均分87.5
原理:Python 的多返回值其实是返回了一个元组(tuple),接收时自动拆开。你暂时不用管元组是什么,记住"返回几个值,就用几个变量接"就行。
多返回值在实战中非常常用。比如一个函数既要返回计算结果,又要返回状态信息(成功/失败),用一个 return 搞定。
七、函数调用流程:程序是怎么跑的
理解函数调用的执行顺序,对后面排错非常重要。
来看一段代码的执行过程:
def calculate_bmi(weight, height):
"""计算BMI指数"""
bmi = weight / (height ** 2)
return round(bmi, 1)
# 主程序
print("开始计算")
result = calculate_bmi(70, 1.75)
print(f"你的BMI是:{result}")
print("计算结束")
执行流程:
- 第1-4行:Python 读到
def,记住有这个函数,但不执行函数体 - 第7行:执行
print("开始计算")→ 屏幕显示"开始计算" - 第8行:调用
calculate_bmi(70, 1.75)→ 跳进函数内部 - 函数内:
weight = 70,height = 1.75,计算bmi = 70 / (1.75 ** 2)= 22.9 return round(bmi, 1)→ 把 22.9 交还给调用处,跳出函数- 第8行:
result拿到 22.9 - 第9行:执行
print(f"你的BMI是:{result}")→ 屏幕显示 - 第10行:执行
print("计算结束")→ 屏幕显示
运行结果:
开始计算
你的BMI是:22.9
计算结束
关键理解:调用函数时,程序会"暂停"主程序,跳进函数里执行,执行完(遇到
return 或函数体结束)再"跳回"主程序继续往下走。就像你正在做饭,发现需要酱油,停下来去拿酱油,拿回来继续做。
八、参数默认值:让参数可选
8.1 什么是默认值
有时候函数的某个参数大部分情况下取值都一样,每次调用都要写一遍很烦。Python 允许你给参数设置默认值:
def greet(name, greeting="你好"):
print(f"{greeting},{name}!")
# 不传 greeting,自动用默认值"你好"
greet("小明") # 你好,小明!
# 传了 greeting,用传入的值
greet("小明", "嗨") # 嗨,小明!
运行结果:
你好,小明!
嗨,小明!
8.2 默认值的位置规则
有默认值的参数必须放在没有默认值的参数后面:
# ✅ 正确:有默认值的在后
def greet(name, greeting="你好"):
print(f"{greeting},{name}!")
# ❌ 错误:有默认值的在前
# def greet(greeting="你好", name):
# print(f"{greeting},{name}!")
为什么?因为 Python 按位置匹配参数,如果默认参数在前面,调用时 Python 就分不清你传的值到底给谁。记住这个规则:普通参数在前,默认参数在后。
默认参数的更多用法(比如
*args、**kwargs)会在下一章详细讲,这里先掌握基本用法。
九、Scratch 积木对照
| Scratch | Python | 说明 |
|---|---|---|
| 「自制积木」→ 定义积木 | def 函数名(): |
把一段代码封装成可复用的积木 |
| 积木的「输入项」 | def 函数名(参数): |
给积木添加输入项,对应函数参数 |


# Scratch「自制积木」→ Python
def say_hello(name):
print(f"你好,{name}!")
say_hello("小明")
Scratch 里点"自制积木"创建一个新积木,可以添加输入项(数字、文本等);Python 里用 def 定义函数,括号里写参数。调用时 Scratch 拖出积木块,Python 写函数名加括号。
十、综合实战:封装实用小工具集
把本章学的函数定义、参数、返回值、多返回值,结合前面的 if 条件判断和字符串格式化,封装三个实用小工具。
完整源码
# ========================================
# 封装实用小工具集
# 综合运用:函数定义、参数、返回值、if条件判断、字符串格式化
# ========================================
# ---------- 工具1:温度转换 ----------
def convert_temp(value, unit):
"""
温度转换函数
参数:value - 温度数值,unit - 原始单位("C"或"F")
返回:转换后的温度(保留1位小数)和说明文字
"""
if unit == "C":
# 摄氏 → 华氏:F = C * 9/5 + 32
result = value * 9 / 5 + 32
return round(result, 1), f"{value}°C = {round(result, 1)}°F"
elif unit == "F":
# 华氏 → 摄氏:C = (F - 32) * 5/9
result = (value - 32) * 5 / 9
return round(result, 1), f"{value}°F = {round(result, 1)}°C"
else:
return None, f"不支持的单位:{unit}(请输入 C 或 F)"
# ---------- 工具2:BMI计算 ----------
def calc_bmi(weight, height):
"""
BMI计算函数
参数:weight - 体重(kg),height - 身高(m)
返回:BMI值和健康等级
"""
bmi = weight / (height ** 2)
bmi = round(bmi, 1)
if bmi < 18.5:
level = "偏瘦"
elif bmi < 24:
level = "正常"
elif bmi < 28:
level = "偏胖"
else:
level = "肥胖"
return bmi, level
# ---------- 工具3:密码强度检测 ----------
def check_password(password):
"""
密码强度检测函数
参数:password - 密码字符串
返回:强度等级和改进建议
"""
length = len(password)
has_upper = False # 是否有大写字母
has_lower = False # 是否有小写字母
has_digit = False # 是否有数字
for char in password:
if char.isupper():
has_upper = True
elif char.islower():
has_lower = True
elif char.isdigit():
has_digit = True
# 计算满足条件的个数
score = 0
if length >= 8:
score += 1
if has_upper:
score += 1
if has_lower:
score += 1
if has_digit:
score += 1
# 根据得分判断强度
if score <= 1:
return "弱", "建议:至少8位,包含大小写字母和数字"
elif score <= 2:
return "中", "建议:增加密码长度,加入更多字符类型"
elif score == 3:
return "较强", "建议:再加入数字或大写字母会更安全"
else:
return "强", "密码强度合格,继续保持!"
# ---------- 主程序:调用三个工具 ----------
print("=" * 40)
print(" 实用小工具集 v1.0")
print("=" * 40)
# 测试温度转换
print("\n【温度转换】")
temp_value, temp_msg = convert_temp(37, "C")
print(temp_msg)
temp_value, temp_msg = convert_temp(100, "F")
print(temp_msg)
# 测试BMI计算
print("\n【BMI计算】")
bmi_value, bmi_level = calc_bmi(70, 1.75)
print(f"BMI指数:{bmi_value}({bmi_level})")
bmi_value, bmi_level = calc_bmi(55, 1.60)
print(f"BMI指数:{bmi_value}({bmi_level})")
# 测试密码强度检测
print("\n【密码强度检测】")
pwd_list = ["123", "abc12345", "Abc12345", "MyPass2024"]
for pwd in pwd_list:
strength, advice = check_password(pwd)
print(f"密码「{pwd}」→ 强度:{strength}({advice})")
print("\n" + "=" * 40)
print(" 工具集演示完毕")
print("=" * 40)
运行结果:
========================================
实用小工具集 v1.0
========================================
【温度转换】
37°C = 98.6°F
100°F = 37.8°C
【BMI计算】
BMI指数:22.9(正常)
BMI指数:21.5(正常)
【密码强度检测】
密码「123」→ 强度:弱(建议:至少8位,包含大小写字母和数字)
密码「abc12345」→ 强度:中(建议:增加密码长度,加入更多字符类型)
密码「Abc12345」→ 强度:较强(建议:再加入数字或大写字母会更安全)
密码「MyPass2024」→ 强度:强(密码强度合格,继续保持!)
分步拆解
工具1:温度转换 convert_temp(value, unit)
- 接收两个参数:温度数值和单位(“C"或"F”)
- 用
if-elif判断单位:"C"走摄氏转华氏公式,"F"走华氏转摄氏公式 round(result, 1)保留1位小数- 返回两个值:转换后的数值和格式化说明文字
- 如果单位不合法,返回
None和错误提示
工具2:BMI计算 calc_bmi(weight, height)
- 接收体重和身高,用公式
体重 / 身高²计算 - 用
if-elif-else根据BMI值划分四个等级:偏瘦、正常、偏胖、肥胖 - 返回BMI数值和等级文字
工具3:密码强度检测 check_password(password)
- 接收密码字符串,先用
len()获取长度 - 逐个字符检查:
.isupper()是否大写、.islower()是否小写、.isdigit()是否数字 - 四个条件各计1分(长度≥8、有大写、有小写、有数字),满分4分
- 根据得分返回强度等级和改进建议
这三个函数都是"输入参数 → 内部处理 →
return返回结果"的标准结构。你以后写的函数基本都是这个套路。注意convert_temp和calc_bmi都用了多返回值,调用时用两个变量接收。
十一、常见报错速查表
| 报错信息 | 出现场景 | 原因 | 解决方法 |
|---|---|---|---|
NameError: name 'greet' is not defined |
调用函数时 | 函数定义写在调用之后,或函数名拼写错误 | 把 def 定义移到调用之前,检查函数名拼写 |
TypeError: greet() missing 1 required positional argument: 'name' |
调用带参数的函数时 | 函数需要参数但调用时没传 | 补上参数:greet("小明") |
TypeError: greet() takes 1 positional argument but 2 were given |
调用函数时 | 函数只定义了1个参数,调用时传了2个 | 检查参数个数,按定义的个数传 |
TypeError: unsupported operand type(s) for +: 'int' and 'str' |
函数内部运算时 | 传入了错误类型的数据(比如需要数字却传了字符串) | 调用时做类型转换:int(input(...)) |
IndentationError: expected an indented block |
定义函数时 | def 冒号后没有缩进的代码块 | 至少写一行缩进代码,或写 pass |
SyntaxError: non-default argument follows default argument |
定义带默认值的参数时 | 有默认值的参数放在了没有默认值的参数前面 | 调整顺序:普通参数在前,默认参数在后 |
十三、本章小结
本章你掌握了 Python 函数的基础全套知识:
- def 定义函数——
def 函数名():把一段代码打包,调用时写函数名加括号 - 形参与实参——定义时写形参(占位变量),调用时传实参(具体值),按顺序一一对应
- return 返回值——把结果交还给调用处,同时结束函数;没写
return则返回None - 多返回值——
return a, b, c一次返回多个值,调用时用对应数量的变量接收 - 函数调用流程——主程序暂停→跳进函数执行→遇到
return跳回主程序继续 - 参数默认值——
def fn(a, b=10)让参数可选,默认参数必须放在普通参数后面
函数是编程中最重要的代码复用方式。以前你写 20 行代码只能用一次,现在封装成函数,一行调用就能复用。
往期回顾:
零基础学 Python 第1章 | 全平台装环境 + VS Code 配置 + 第一个 Hello World
零基础学 Python 第2章 | print 输出 + 变量赋值 + input 交互输入
零基础学 Python 第3章 | 条件判断:if / elif / else
零基础学 Python 第 4 章 | for 循环与 range():让程序帮你重复干活
零基础学 Python 第 5 章 | while 循环与循环嵌套:让程序看着条件自己干活
零基础学 Python 第 6 章 | 元组与集合:不可变数据与自动去重
零基础学 Python 第7章 | 字典 dict:键值对存储
下一章预告:本章的函数已经能用了,但参数的玩法远不止于此。下一章学习函数进阶——默认参数的坑(可变默认值问题)、*args 和 **kwargs(任意数量参数)、变量作用域(局部变量 vs 全局变量),让你的函数更灵活更强大。
文末资源区
| 资源 | 说明 |
|---|---|
| Python 官方文档 - 函数定义 | https://docs.python.org/3/tutorial/controlflow.html#defining-functions |
| Python 官方文档 - 函数参数 | https://docs.python.org/3/tutorial/controlflow.html#more-on-defining-functions |
Python 官方文档 - return 语句 |
https://docs.python.org/3/reference/simple_stmts.html#the-return-statement |
| 本章完整源码 | chapter9_all.py(关注梅雅达编程笔记,评论领资料) |
每节课都配套课后练习题与完整源码。代码报错、看不懂知识点,可在评论区粘贴问题,逐一解答!
欢迎关注梅雅达编程笔记,持续分享Python零基础学习内容
更多推荐





所有评论(0)