本章摘要

  1. 核心目标:学会用 def 定义函数,把代码打包成可复用的工具
  2. 核心知识点:def 定义函数、形参与实参、return 返回值、多返回值、函数调用流程、参数默认值
  3. 实操产出:封装温度转换、BMI计算、密码强度检测三个实用函数工具集
  4. 前置基础:第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岁,来自北京

参数的顺序很重要。调用时实参会按顺序一一对应:第一个实参给第一个形参,第二个给第二个……所以 "小明" 对应 name18 对应 age"北京" 对应 city


五、return 返回值:让函数给出结果

5.1 printreturn 的区别

这是新手最容易搞混的地方。

  • 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 有两个作用

  1. 返回一个值给调用处
  2. 立即结束函数——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. 第1-4行:Python 读到 def,记住有这个函数,但不执行函数体
  2. 第7行:执行 print("开始计算") → 屏幕显示"开始计算"
  3. 第8行:调用 calculate_bmi(70, 1.75) → 跳进函数内部
  4. 函数内:weight = 70height = 1.75,计算 bmi = 70 / (1.75 ** 2) = 22.9
  5. return round(bmi, 1) → 把 22.9 交还给调用处,跳出函数
  6. 第8行:result 拿到 22.9
  7. 第9行:执行 print(f"你的BMI是:{result}") → 屏幕显示
  8. 第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)

  1. 接收两个参数:温度数值和单位(“C"或"F”)
  2. if-elif 判断单位:"C" 走摄氏转华氏公式,"F" 走华氏转摄氏公式
  3. round(result, 1) 保留1位小数
  4. 返回两个值:转换后的数值和格式化说明文字
  5. 如果单位不合法,返回 None 和错误提示

工具2:BMI计算 calc_bmi(weight, height)

  1. 接收体重和身高,用公式 体重 / 身高² 计算
  2. if-elif-else 根据BMI值划分四个等级:偏瘦、正常、偏胖、肥胖
  3. 返回BMI数值和等级文字

工具3:密码强度检测 check_password(password)

  1. 接收密码字符串,先用 len() 获取长度
  2. 逐个字符检查:.isupper() 是否大写、.islower() 是否小写、.isdigit() 是否数字
  3. 四个条件各计1分(长度≥8、有大写、有小写、有数字),满分4分
  4. 根据得分返回强度等级和改进建议

这三个函数都是"输入参数 → 内部处理 → return 返回结果"的标准结构。你以后写的函数基本都是这个套路。注意 convert_tempcalc_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 函数的基础全套知识:

  1. def 定义函数——def 函数名(): 把一段代码打包,调用时写函数名加括号
  2. 形参与实参——定义时写形参(占位变量),调用时传实参(具体值),按顺序一一对应
  3. return 返回值——把结果交还给调用处,同时结束函数;没写 return 则返回 None
  4. 多返回值——return a, b, c 一次返回多个值,调用时用对应数量的变量接收
  5. 函数调用流程——主程序暂停→跳进函数执行→遇到 return 跳回主程序继续
  6. 参数默认值——def fn(a, b=10) 让参数可选,默认参数必须放在普通参数后面

函数是编程中最重要的代码复用方式。以前你写 20 行代码只能用一次,现在封装成函数,一行调用就能复用。

往期回顾:

《Python 零基础入门:从积木到代码》专栏序

零基础学 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:键值对存储

零基础学 Python 第8章 | 字符串操作与格式化输出

下一章预告:本章的函数已经能用了,但参数的玩法远不止于此。下一章学习函数进阶——默认参数的坑(可变默认值问题)、*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零基础学习内容

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐