函数是Python编程的核心基石,也是从"入门代码"迈向"规范代码、工程代码"的第一道门槛。学会函数,我们就能彻底告别复制粘贴冗余代码,实现代码复用、简化逻辑、降低维护成本。
本节课将从零带大家吃透Python函数所有核心知识点:从函数概念、定义调用,到参数、返回值、变量作用域,再到函数嵌套、链式调用、递归原理,搭配大量可运行代码、通俗类比和实战最佳实践,零基础也能轻松看懂!
1 为什么要学习函数?函数核心概念
1.1 函数是什么?
编程中的函数,本质是一段可重复调用、功能独立的代码片段 ,核心作用:代码复用、简化逻辑、便于维护。
类比数学函数:数学中 y=f(x) 输入x输出y;编程函数输入参数,执行逻辑后输出结果,核心是「映射关系」。
1.2 冗余代码痛点演示(无函数写法)
需求:分别计算 1-50、200-300、1-500 的整数累加和,不使用函数时代码极度冗余:
python
# 1. 计算1-50累加和
sum1 = 0
for i in range(1, 51):
sum1 += i
print("1-50和:", sum1)
# 2. 计算200-300累加和
sum2 = 0
for i in range(200, 301):
sum2 += i
print("200-300和:", sum2)
# 3. 计算1-500累加和
sum3 = 0
for i in range(1, 501):
sum3 += i
print("1-500和:", sum3)
存在问题:三段代码逻辑完全一致,仅数值不同,重复代码过多,若需要修改累加逻辑(如改为累乘),需要修改三处代码,维护成本极高。
1.3 函数优化写法(代码复用实战)
将重复的累加逻辑封装为函数,一次定义、随处调用:
python
# 定义累加求和函数
def calc_total(start, end):
total = 0
for i in range(start, end + 1):
total += i
print(f"{start}-{end}和:{total}")
# 多次调用函数,无需重复写逻辑
calc_total(1, 50)
calc_total(200, 300)
calc_total(1, 500)
优化优势:逻辑只写一次,后续修改只需改函数内部,所有调用位置自动生效,彻底解决代码冗余问题。
1.4 开发最佳实践
-
任何重复3次及以上的代码,必须封装为函数;
-
一个函数只实现一个核心功能,功能单一、逻辑清晰;
-
函数命名见名知意,禁止使用拼音、无意义字符(如func1、a1)。
2 函数标准语法:定义与调用
2.1 函数定义语法
Python通过def 关键字定义函数,固定格式:
python
def 函数名(形参列表):
# 函数体(必须缩进)
逻辑代码
return 返回值 # 可选,可省略
说明:
-
形参列表:可为空(无参函数)、单个或多个参数;
-
函数体必须带一级缩进,无缩进代码不属于函数;
-
return 可选,无return时函数默认返回None。
2.2 函数调用语法
python
# 方式1:无需接收返回值
函数名(实参列表)
# 方式2:接收函数返回值(推荐开发用法)
变量 = 函数名(实参列表)
2.3 核心规则(必记)
-
先定义,后调用:函数未定义就调用,直接报 NameError 错误;
-
函数定义不执行代码,只有调用才会执行,调用几次执行几次;
-
函数可无限次重复调用,无需重复定义。
错误示例(先调用后定义):
python
hello() # 报错:NameError
def hello():
print("Hello Python")
2.4 代码警告与错误区分(PEP8规范)
很多新手分不清代码「错误」和「警告」:
-
错误(Error):代码语法/逻辑出错,程序无法运行,必须修改;
-
警告(Warning):符合PEP8编程规范建议,不影响程序运行,可忽略或优化。
PEP8是Python官方编程规范,核心要求:代码整洁、命名规范、格式统一,企业开发优先遵循。
3 函数参数:形参、实参、默认参数、关键字参数
3.1 形参与实参核心概念
-形参(形式参数):定义函数时括号中的参数,仅占位,无实际值;
- 实参(实际参数):调用函数时传入的真实数据,用于给形参赋值。
示例:
python
# start、end 是形参
def calc_total(start, end):
total = 0
for i in range(start, end+1):
total += i
return total
# 1、50 是实参,调用时 start=1,end=50
res = calc_total(1, 50)
3.2 参数匹配规则
-
普通位置参数:实参与形参个数必须一致,一一对应,顺序匹配;
-
Python是动态类型语言,形参无需指定数据类型,可接收任意类型数据(数字、字符串、列表等)。
3.3 默认参数用法与避坑
默认参数:定义函数时为形参设置默认值,调用时若不传该参数,自动使用默认值。
硬性规则 :带默认值的参数,必须放在无默认值参数的后方,否则报语法错误!
正确示例:
python
# debug为默认参数,默认关闭调试
def add_num(a, b, debug=False):
if debug:
print(f"调试参数:a={a}, b={b}")
return a + b
# 不传默认参数,使用默认值False
print(add_num(10, 20))
# 传参覆盖默认值,开启调试
print(add_num(10, 20, True))
3.4 关键字参数用法与优势
普通传参是「位置传参」,必须严格对应顺序;关键字参数通过「参数名=值」的形式传参,可无视顺序。
示例:
python
def student_info(name, age, gender):
print(f"姓名:{name},年龄:{age},性别:{gender}")
# 关键字参数,打乱顺序传参
student_info(age=18, name="小明", gender="男")
# 位置参数+关键字参数混用(位置参数必须在前)
student_info("小红", gender="女", age=17)
3.5 开发最佳实践
-
固定参数使用位置传参,可选参数设置默认值;
-
参数较多时优先使用关键字传参,代码可读性更高;
-
禁止位置参数放在关键字参数后方。
4 函数返回值:单返回值、多返回值、return特性
4.1 返回值核心概念
参数是函数的输入 ,返回值是函数的输出。函数执行完毕后,通过return将结果返回给调用者。
开发核心原则:逻辑与交互分离!函数只负责计算逻辑,打印、保存文件等交互操作放在函数外部,提升代码通用性。
4.2 单返回值实战(优化前后对比)
不推荐(函数兼顾计算+打印,通用性差):
python
def calc_total(start, end):
total = 0
for i in range(start, end+1):
total += i
print(total) # 函数内部打印,只能控制台输出
推荐(只做计算,灵活复用):
python
def calc_total(start, end):
total = 0
for i in range(start, end+1):
total += i
return total # 返回结果,交由调用者处理
# 可自由打印、存文件、运算
res = calc_total(1, 100)
print("计算结果:", res)
4.3 return核心特性
-
执行到return,函数立即终止,后续代码不会执行;
-
函数可存在多个return,搭配分支语句使用;
-
无return的函数,默认返回 None。
示例:判断奇偶(多return)
python
def is_even(num):
if num % 2 == 0:
return True # 偶数,直接返回,函数结束
return False # 奇数返回
print(is_even(10)) # True
print(is_even(7)) # False
4.4 多返回值用法与占位符_
Python独有特性:一个函数可一次性返回多个值,多个返回值用逗号分隔。
示例:返回坐标xy值
python
def get_pos():
x = 100
y = 200
return x, y # 返回两个值
# 接收全部返回值
x, y = get_pos()
print(x, y)
# 只接收部分值,无用值用 _ 占位(开发常用)
_, y = get_pos()
print("只获取y坐标:", y)
5 变量作用域:全局变量、局部变量、global关键字
变量作用域:变量的有效生效范围,分为全局变量和局部变量。
5.1 作用域分类
-全局变量:定义在函数外部,整个程序生效;
- 局部变量:定义在函数内部,仅当前函数生效,函数执行结束自动销毁。
5.2 五大核心规则
-
局部变量仅函数内部有效,外部无法访问;
-
不同作用域允许同名变量,互不干扰;
-
函数内部优先查找局部变量,局部无则查找全局变量;
-
if/for/while 普通代码块不产生作用域,内部变量外部可访问;
-
函数内部修改全局变量,必须用 global 关键字声明。
5.3 global关键字实战
python
# 全局变量
num = 100
def modify_num():
global num # 声明num为全局变量
num = 200 # 修改全局变量
modify_num()
print("修改后的全局变量:", num) # 输出200
若无global声明,函数内的num=200会被认定为局部变量,不会修改全局值。
6 函数执行流程与调试技巧
6.1 执行底层逻辑
-
程序从上至下执行,读取函数定义,仅加载不执行;
-
遇到函数调用,跳转至函数内部执行代码;
-
函数执行完毕/遇到return,返回调用位置,继续向下执行。
6.2 PyCharm断点调试教程
-
点击代码行号右侧空白,添加断点(红色圆点);
-
右键代码选择 Debug 模式运行;
-
按 F7 逐行执行(Step Into),可进入函数内部观察执行过程;
-
左下角可查看函数调用栈、栈帧、局部变量,精准排查BUG。
7 函数链式调用与嵌套调用
7.1 链式调用
概念:将一个函数的返回值,作为另一个函数的参数,简化代码层级。
示例:
python
def add(a, b):
return a + b
def judge_even(num):
return num % 2 == 0
# 链式调用:先执行add,结果传入judge_even
print(judge_even(add(10, 20)))
7.2 嵌套调用
概念:在一个函数内部,调用另一个函数,支持多层嵌套。
示例:
python
def func_a():
print("执行函数A")
def func_b():
func_a() # 嵌套调用A
print("执行函数B")
func_b()
执行顺序:调用func_b → 执行func_a → 执行func_b剩余代码。
7.3 函数栈帧
每次调用函数,系统会自动创建一个独立栈帧,存储当前函数的局部变量;
函数执行结束,栈帧销毁,局部变量随之释放;
多层嵌套函数的同名变量,存储在不同栈帧,互不干扰。
8 函数递归:原理、实战、优缺点
8.1 递归概念
递归是特殊的嵌套调用:函数内部调用自身。
通俗类比:从前有座山,山里有座庙,庙里有个老和尚讲故事,故事内容是"从前有座山..."。
8.2 递归必备两大条件
-
终止条件:避免无限递归(栈溢出报错);
-
递推逻辑:每次递归参数逐步逼近终止条件。
8.3 实战:递归计算阶乘
需求:计算 n! = 1*2*3*...*n,递归公式:n! = n\*(n-1)!,终止条件:1! = 1
python
def factorial(n):
# 终止条件
if n == 1:
return 1
# 递推逻辑
return n * factorial(n-1)
print(factorial(5)) # 输出120
8.4 递归优缺点
优点:代码简洁、贴合数学逻辑,适合树形、层级类问题;
缺点:递归层数过多易栈溢出、执行效率低于循环、逻辑晦涩难调试;
开发结论:优先循环,复杂层级算法(遍历、回溯)再慎用递归。
9 函数核心知识点总结
-
函数核心价值:代码复用、降低维护成本、逻辑解耦;
-
核心语法:def定义、括号传参、return返回值、先定义后调用;
-
参数类型:位置参数、默认参数、关键字参数(注意参数顺序规则);
-
作用域:局部变量仅内部生效,global修改全局变量,普通代码块无作用域;
-
高级用法:链式调用简化代码、嵌套调用拆分逻辑、递归解决层级问题;
-
开发规范:单一职责、逻辑交互分离、命名规范、慎用递归。