前两课我们依次掌握了「数据存储(核心数据类型)」和「逻辑执行(流程控制)」,能写出具备完整功能的 Python 程序,但会发现一个问题:相同的功能代码会反复出现,程序结构杂乱、冗余且难以维护。本节课要学的函数,就是解决这个问题的核心 —— 将重复使用的代码块「封装」成独立的函数,实现一次编写、多次调用,让代码更简洁、更易维护、更具复用性。函数是 Python 模块化编程的基础,也是进阶开发的核心技能,掌握它,你的编程能力将实现质的飞跃。

一、课程目标

✅ 掌握函数的定义调用,理解函数的核心作用;✅ 吃透函数的 4 类参数:位置参数、关键字参数、默认参数、不定长参数,灵活传递数据;✅ 掌握return返回值的用法,实现函数与主程序的数据交互;✅ 理解函数的嵌套调用、递归调用基础逻辑,拓展编程思维;✅ 分清全局变量与局部变量,规避变量作用域的常见错误;✅ 能将前序知识(数据类型、流程控制)封装为函数,完成实战开发;✅ 建立「模块化编程」思维,学会用函数拆分复杂需求。

二、复习回顾:为什么需要函数?(函数的诞生意义)

前两课我们写的代码都是「线性执行」的,存在两个致命问题:

  1. 代码冗余:相同功能(如成绩平均分计算、列表遍历)需要反复写重复代码,效率极低;
  2. 维护困难:若要修改某个功能,需要在所有重复代码处逐一修改,极易遗漏出错。

函数的核心价值:把实现特定功能的代码块「打包」,起一个专属名字,后续需要该功能时,直接调用这个名字即可,无需重复写代码。本质是 代码复用 + 功能解耦 + 结构优化

python

运行

# 无函数的弊端:重复代码(计算2组成绩的平均分,代码重复)
# 第一组成绩计算
scores1 = [85,92,78]
avg1 = sum(scores1)/len(scores1)
print(f"第一组平均分:{avg1:.1f}")

# 第二组成绩计算(和上面代码完全重复)
scores2 = [90,88,95]
avg2 = sum(scores2)/len(scores2)
print(f"第二组平均分:{avg2:.1f}")

# 有函数的优势:一次封装,多次调用(后续学完函数即可实现)
# calc_avg(scores1)、calc_avg(scores2) 直接调用,无重复代码

三、核心知识点 1:函数的基础 —— 定义与调用(入门必备)

3.1 什么是函数?

函数是 组织好的、可重复使用的、实现单一功能的代码块。Python 中所有功能的实现,本质都是调用各种函数(内置函数如print()len(),自定义函数如我们自己写的功能块)。

3.2 函数的定义语法(核心)

Python 中用关键字 def 定义函数,语法严格遵循「冒号 + 缩进」规则,是必须背熟的基础语法:

python

运行

def 函数名(参数列表):  # 1.def关键字 + 函数名 + 括号 + 参数(可选) + 冒号
    """函数文档注释(可选,说明函数功能、参数、返回值)""" # 2.可选:增强代码可读性
    函数体代码块       # 3.核心:实现功能的代码(必须缩进,4个空格/Tab)
    [return 返回值]    # 4.可选:函数执行完毕后,向调用者返回数据
✅ 语法说明
  1. 函数名:遵循变量命名规则(字母 / 数字 / 下划线,不能以数字开头,见名知意);
  2. 参数列表:可选,用于接收外部传递给函数的数据,多个参数用逗号分隔;
  3. 函数文档注释:用三引号包裹,推荐必写,方便他人 / 自己理解函数功能;
  4. 函数体:实现函数核心功能的代码,必须缩进;
  5. return:可选,用于返回函数执行结果,无 return 则默认返回None

3.3 无参函数(入门首学,最简单的函数)

无参函数:定义时参数列表为空,无需接收外部数据,直接调用即可执行功能,适合实现「固定功能」。

✅ 示例 1:定义并调用一个简单的无参函数

python

运行

# 定义无参函数:打印欢迎语
def print_welcome():
    """打印程序欢迎语,无参数、无返回值"""
    print("="*20)
    print("欢迎使用Python程序")
    print("="*20)

# 调用函数:函数名+括号,执行函数体代码
print_welcome()
✅ 运行结果

plaintext

====================
欢迎使用Python程序
====================

💡 关键规则:函数必须「先定义,后调用」,若调用在定义之前,会直接报错NameError

✅ 示例 2:多次调用函数(体现代码复用优势)

python

运行

def say_hello():
    """打印问候语"""
    print("Hello Python!")

# 一次定义,多次调用(无需重复写print代码)
say_hello()
say_hello()
say_hello()
✅ 运行结果

plaintext

Hello Python!
Hello Python!
Hello Python!

3.4 函数的调用本质

函数的调用过程,可理解为 3 个步骤:

  1. 程序执行到「函数名 ()」时,跳转到函数定义的位置;
  2. 执行函数体内的所有代码;
  3. 函数执行完毕(或遇到return),回到调用位置,继续执行后续代码。

四、核心知识点 2:函数的参数 —— 实现函数与外部的数据交互

无参函数只能实现固定功能,灵活性不足;参数 是函数的「输入口」,用于接收外部传递的数据,让函数能根据不同输入,实现不同结果,是函数的核心灵活点。Python 的参数分为 4 类,由浅入深逐一掌握。

4.1 位置参数(必传参数,最基础)

位置参数:定义时按顺序声明参数,调用时必须按「相同顺序」传递对应数量的参数,缺一不可、多一不行,是最常用的参数类型。

✅ 语法与示例(成绩平均分计算函数)

python

运行

# 定义带位置参数的函数:接收成绩列表,计算平均分
def calc_avg(scores):
    """接收成绩列表,返回平均分(保留1位小数)"""
    avg = sum(scores) / len(scores)
    return round(avg, 1)

# 调用函数:按位置传递参数(参数顺序必须和定义一致)
math_scores = [85,92,78,90]
chinese_scores = [95,88,82,79]

# 多次调用,传递不同参数,得到不同结果
math_avg = calc_avg(math_scores)
chinese_avg = calc_avg(chinese_scores)

print(f"数学平均分:{math_avg}")
print(f"语文平均分:{chinese_avg}")
✅ 运行结果

plaintext

数学平均分:86.2
语文平均分:86.0
✅ 多位置参数示例(按顺序传递)

python

运行

# 定义2个位置参数:计算两数之和
def add_num(a, b):
    """接收两个数字,返回两数之和"""
    return a + b

# 调用:按顺序传递,a=10,b=20
res1 = add_num(10, 20)
# 调用:按顺序传递,a=3.5,b=6.5
res2 = add_num(3.5, 6.5)

print(f"10+20={res1}")
print(f"3.5+6.5={res2}")
✅ 运行结果

plaintext

10+20=30
3.5+6.5=10.0

4.2 关键字参数(解耦参数顺序,调用更清晰)

关键字参数:调用函数时,通过「参数名 = 值」的形式传递数据,无需遵循参数定义的顺序,适合参数较多的场景,能大幅提升代码可读性。

✅ 示例(对比位置参数与关键字参数)

python

运行

# 定义3个位置参数:打印学生信息
def print_student(name, age, score):
    """打印学生姓名、年龄、成绩"""
    print(f"姓名:{name},年龄:{age},成绩:{score}")

# 方式1:位置参数(必须按顺序传递)
print_student("张三", 20, 95)

# 方式2:关键字参数(无需按顺序,更清晰)
print_student(age=21, name="李四", score=88)

# 方式3:混合使用(位置参数在前,关键字参数在后,推荐)
print_student("王五", score=90, age=19)
✅ 运行结果

plaintext

姓名:张三,年龄:20,成绩:95
姓名:李四,年龄:21,成绩:88
姓名:王五,年龄:19,成绩:90

💡 注意:混合使用时,位置参数必须放在关键字参数前面,否则报错SyntaxError

4.3 默认参数(给参数赋默认值,简化调用)

默认参数:定义函数时,给参数指定「默认值」,调用时若不传该参数,则使用默认值;若传递,则覆盖默认值。适合「参数值相对固定」的场景,能大幅简化函数调用。

✅ 语法与示例(带默认参数的函数)

python

运行

# 定义默认参数:gender默认值为"男",score默认值为60
def create_student(name, age, gender="男", score=60):
    """创建学生信息,性别默认男,成绩默认60"""
    student = {
        "name": name,
        "age": age,
        "gender": gender,
        "score": score
    }
    return student

# 调用1:不传默认参数,使用默认值
stu1 = create_student("张三", 20)
# 调用2:传递gender,覆盖默认值,score用默认值
stu2 = create_student("李四", 21, "女")
# 调用3:所有参数都传递,全部覆盖默认值
stu3 = create_student("王五", 19, "男", 95)

print(stu1)
print(stu2)
print(stu3)
✅ 运行结果

plaintext

{'name': '张三', 'age': 20, 'gender': '男', 'score': 60}
{'name': '李四', 'age': 21, 'gender': '女', 'score': 60}
{'name': '王五', 'age': 19, 'gender': '男', 'score': 95}

💡 重要规则:默认参数必须放在位置参数后面,否则报错;默认参数的默认值,建议使用「不可变类型」(str/int/tuple),避免踩坑。

4.4 不定长参数(接收任意数量的参数,万能适配)

开发中常会遇到「参数数量不确定」的场景(如计算任意多个数的和),不定长参数 可接收任意数量的参数,完美解决该问题,Python 提供两种核心不定长参数:*args**kwargs

✅ 类型 1:*args —— 接收任意数量的「位置参数」,打包为元组

python

运行

# 定义*args参数:计算任意多个数字的和
def sum_nums(*args):
    """接收任意数量的数字,返回总和"""
    print(f"args的类型:{type(args)},内容:{args}") # args是元组
    total = 0
    for num in args:
        total += num
    return total

# 调用:传递任意数量的参数,均可接收
res1 = sum_nums(10,20)
res2 = sum_nums(1,2,3,4,5)
res3 = sum_nums(0.5, 1.5, 2.5)

print(f"10+20={res1}")
print(f"1+2+3+4+5={res2}")
print(f"0.5+1.5+2.5={res3}")
✅ 运行结果

plaintext

args的类型:<class 'tuple'>,内容:(10, 20)
args的类型:<class 'tuple'>,内容:(1, 2, 3, 4, 5)
args的类型:<class 'tuple'>,内容:(0.5, 1.5, 2.5)
10+20=30
1+2+3+4+5=15
0.5+1.5+2.5=4.5
✅ 类型 2:**kwargs —— 接收任意数量的「关键字参数」,打包为字典

python

运行

# 定义**kwargs参数:接收任意数量的关键字参数,打印信息
def print_info(**kwargs):
    """接收任意数量的关键字参数,打印键值对信息"""
    print(f"kwargs的类型:{type(kwargs)},内容:{kwargs}") # kwargs是字典
    for key, value in kwargs.items():
        print(f"{key}:{value}")

# 调用:传递任意数量的关键字参数
print_info(name="张三", age=20)
print("-"*20)
print_info(name="李四", gender="女", score=95, address="北京市")
✅ 运行结果

plaintext

kwargs的类型:<class 'dict'>,内容:{'name': '张三', 'age': 20}
name:张三
age:20
--------------------
kwargs的类型:<class 'dict'>,内容:{'name': '李四', 'gender': '女', 'score': 95, 'address': '北京市'}
name:李四
gender:女
score:95
address:北京市

五、核心知识点 3:函数的返回值 —— 实现函数向外部传递数据

函数执行完毕后,若需要将内部的计算结果、处理数据传递给调用者,就需要用到 返回值,核心关键字为 return,是函数与外部交互的「输出口」。

5.1 return 的基础用法

✅ 规则 1:无 return 语句,函数默认返回None

python

运行

def func1():
    print("无return的函数")

res = func1()
print(f"func1的返回值:{res},类型:{type(res)}")
✅ 运行结果

plaintext

无return的函数
func1的返回值:None,类型:<class 'NoneType'>
✅ 规则 2:return + 单个值,返回指定数据

python

运行

def get_pi():
    """返回圆周率近似值"""
    return 3.1415926

pi = get_pi()
print(f"圆周率:{pi}")
print(f"圆的面积(半径2):{pi * 2**2}")
✅ 运行结果

plaintext

圆周率:3.1415926
圆的面积(半径2):12.5663704
✅ 规则 3:return + 多个值,自动打包为「元组」返回

python

运行

def get_score():
    """返回语文、数学、英语成绩"""
    chinese = 95
    math = 92
    english = 88
    return chinese, math, english  # 多个值,自动转为元组

# 接收方式1:整体接收(元组)
scores = get_score()
print(f"成绩元组:{scores}")

# 接收方式2:解包接收(推荐,更清晰)
ch, ma, en = get_score()
print(f"语文:{ch},数学:{ma},英语:{en}")
✅ 运行结果

plaintext

成绩元组:(95, 92, 88)
语文:95,数学:92,英语:88

5.2 return 的进阶特性:提前终止函数

函数执行过程中,遇到 return 会立即终止执行,后续代码不再运行,可用于提前结束函数逻辑。

python

运行

def check_score(score):
    """判断成绩是否及格,及格返回True,否则返回False"""
    if score >=60:
        return True  # 满足条件,立即返回,后续代码不执行
    return False

res1 = check_score(85)
res2 = check_score(55)

print(f"85分是否及格:{res1}")
print(f"55分是否及格:{res2}")
✅ 运行结果

plaintext

85分是否及格:True
55分是否及格:False

六、核心知识点 4:函数进阶用法(入门必备)

6.1 函数的嵌套调用(函数内调用其他函数)

Python 支持在一个函数内部调用另一个函数,称为「嵌套调用」,是实现复杂功能的核心技巧 —— 将复杂功能拆分为多个小函数,再组合调用,符合「模块化」思想。

✅ 示例(嵌套调用实现成绩统计)

python

运行

# 小函数1:计算平均分
def calc_avg(scores):
    return sum(scores)/len(scores)

# 小函数2:判断是否及格
def is_pass(avg):
    return avg >=60

# 主函数:嵌套调用两个小函数,完成成绩统计
def stat_score(scores):
    avg = calc_avg(scores)  # 调用calc_avg
    pass_flag = is_pass(avg) # 调用is_pass
    return avg, pass_flag

# 调用主函数
math_scores = [85,92,78,59]
avg_score, is_pass_flag = stat_score(math_scores)
print(f"平均分:{avg_score:.1f},是否及格:{is_pass_flag}")
✅ 运行结果

plaintext

平均分:78.5,是否及格:True

6.2 变量的作用域(全局变量 vs 局部变量)

变量的「作用域」指变量能被访问的范围,分为两类,是新手高频易错点,必须吃透!

✅ 类型 1:局部变量 —— 函数内部定义的变量,仅在函数内有效

局部变量在函数执行时创建,函数执行完毕后销毁,外部无法访问。

python

运行

def func():
    a = 100  # 局部变量,仅在func内有效
    print(f"函数内访问a:{a}")

func()
# print(a)  # 报错:NameError,外部无法访问局部变量
✅ 类型 2:全局变量 —— 函数外部定义的变量,整个程序都能访问

全局变量在程序运行时创建,程序结束后销毁,函数内部可直接读取,但修改需用关键字 global 声明。

python

运行

# 全局变量:函数外部定义
b = 200

def func1():
    # 读取全局变量(无需声明)
    print(f"函数内读取全局变量b:{b}")

def func2():
    global b  # 声明:修改的是全局变量b
    b = 300   # 修改全局变量
    print(f"函数内修改全局变量b为:{b}")

func1()
func2()
print(f"函数外访问修改后的b:{b}")
✅ 运行结果

plaintext

函数内读取全局变量b:200
函数内修改全局变量b为:300
函数外访问修改后的b:300

七、综合实操案例(整合前 4 课所有知识,实战核心)

案例 1:封装「学生成绩管理工具包」(函数 + 列表 + 字典 + 流程控制)

✅ 需求:将成绩统计、及格判断、最高分查找等功能,封装为多个函数,实现「工具化调用」,支持批量处理学生成绩;✅ 知识点:函数定义 / 调用、参数传递、返回值、列表 / 字典操作、流程控制;

python

运行

# ========== 学生成绩管理工具包 ==========
def calc_avg(scores):
    """计算平均分,保留1位小数"""
    return round(sum(scores)/len(scores), 1)

def get_max_score(scores):
    """返回最高分"""
    return max(scores)

def get_pass_rate(scores):
    """计算及格率(≥60分),保留1位小数"""
    pass_count = 0
    for score in scores:
        if score >=60:
            pass_count +=1
    return round(pass_count/len(scores)*100, 1)

def stat_all(scores):
    """综合统计:返回平均分、最高分、及格率"""
    avg = calc_avg(scores)
    max_s = get_max_score(scores)
    rate = get_pass_rate(scores)
    return avg, max_s, rate

# 调用工具包
scores = [85,59,92,78,65,48,98]
avg_score, max_score, pass_rate = stat_all(scores)

print("=== 成绩综合统计结果 ===")
print(f"平均分:{avg_score} 分")
print(f"最高分:{max_score} 分")
print(f"及格率:{pass_rate}%")

✅ 运行结果

plaintext

=== 成绩综合统计结果 ===
平均分:75.0 分
最高分:98 分
及格率:71.4%

案例 2:猜数字游戏升级版(函数封装 + 循环 + 条件判断)

✅ 需求:将猜数字游戏的「随机数生成、用户输入、判断逻辑」封装为函数,实现游戏的模块化调用,支持自定义猜数范围;✅ 知识点:函数默认参数、return 终止函数、while 循环、if 判断、随机数模块;

python

运行

import random

def guess_num_game(start=1, end=10):
    """猜数字游戏,默认范围1-10,支持自定义范围"""
    print(f"=== 猜数字小游戏({start}-{end})===")
    target = random.randint(start, end)
    while True:
        user_num = int(input("请输入你猜测的数字:"))
        if user_num == target:
            print("恭喜你,猜对啦!🎉")
            return  # 终止函数,结束游戏
        elif user_num > target:
            print("猜大了,再试试~")
        else:
            print("猜小了,再试试~")

# 调用1:使用默认范围1-10
guess_num_game()

# 调用2:自定义范围1-20(后续可执行)
# guess_num_game(1,20)

八、课后作业(基础 + 进阶,巩固必做)

✅ 基础作业(掌握核心用法)

  1. 定义函数 is_prime(num):接收一个整数,判断是否为质数(质数:大于 1,只能被 1 和自身整除),返回布尔值;
  2. 定义函数 list_reverse(lst):接收一个列表,返回反转后的新列表(不使用列表自带的 reverse () 方法);
  3. 定义带默认参数的函数 print_msg(msg, times=1):打印指定信息,默认打印 1 次,支持自定义打印次数。

✅ 进阶作业(模块化思维锻炼)

  1. 封装「列表工具函数」:包含 3 个函数 —— 列表去重、列表排序(升序)、列表求和,实现批量调用;
  2. 基于质数判断函数,定义函数 find_prime(a, b):返回 a 到 b 之间的所有质数,存入列表并返回;
  3. 思考:函数的「参数」和「返回值」分别解决了什么问题?两者的核心作用是什么?

九、后续学习指引

本节课我们掌握了 Python模块化编程的核心 —— 函数,实现了代码的复用与解耦,让程序从「线性代码」升级为「模块化代码」。👉 下一课我们将学习 Python 高级数据容器与文件操作 —— 掌握集合、有序字典等高级容器,以及文件的读写操作,实现「数据持久化」(将数据保存到文件,程序关闭后数据不丢失),让你的程序具备「数据存储」的实战能力。

十、本节课核心总结

  1. 函数的核心价值:代码复用、功能解耦、结构优化,一次定义、多次调用;
  2. 函数基础语法def 函数名(参数): + 缩进的函数体 + return 返回值,必须先定义后调用;
  3. 4 类参数:位置参数(必传、有序)、关键字参数(无序、清晰)、默认参数(简化调用)、不定长参数(万能适配);
  4. 返回值return 传递数据,可返回单个 / 多个值,遇到 return 立即终止函数;
  5. 作用域:局部变量(函数内有效)、全局变量(全局有效,修改需用 global 声明);
  6. 核心思维:模块化拆分 —— 将复杂功能拆分为多个小函数,嵌套调用实现组合功能。
Logo

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

更多推荐