python核心语法(四)- 函数
一.介绍
1.1 定义
函数是可重复调用的代码块,用来实现特定功能。
1.2 语法
def 函数名(参数1, 参数2, ...):
"""函数文档字符串(可选,说明函数功能)"""
# 函数体:实现功能的代码
执行语句
return 返回值 # 可选,没有则默认返回None
1.3 注意事项
1.参数相关
默认参数:禁用列表 / 字典(可变对象),改用 None(内部初始化:lst = [] if lst is None else lst)
参数顺序:必选 → 默认 → *args → **kwargs(违反直接报错)
可变对象传参:函数内修改会影响外部(传副本lst.copy()避免)
2. 作用域相关
修改全局变量加global,修改嵌套变量加nonlocal
未声明直接赋值全局变量 → 被识别为局部变量(报错)
3. 返回值相关
无 return 的函数 → 默认返回 None(别误判有返回值)
多返回值本质是元组,解包时数量要匹配(否则报错)
4. 递归函数
必须写明确终止条件,递归深度≤约 1000 层(否则报 RecursionError)
二.参数与返回值
2.1参数方式及对比
| 对比维度 | 位置参数 | 默认参数 | 关键字参数 | 可变位置参数 (*args) | 可变关键字参数 (**kwargs) | 解包传参 |
| 参数数量 | 固定 | 固定 | 固定 | 任意数量 | 任意数量 | 固定(解包后) |
| 参数顺序 | 严格要求 | 需在位置参数后定义 | 调用时可打乱 | 无 | 无 | 解包后需匹配函数定义顺序 |
| 接收数据类型 | 单个值 | 单个值 | 单个值 | 元组 | 字典 | 列表 / 元组 / 字典(解包为单个值) |
| 适用场景 | 参数数量固定、顺序明确 | 参数有常用默认值 | 参数多 / 怕记混顺序 | 不确定位置参数数量 | 不确定关键字参数数量 | 已有列表 / 字典,需快速传参 |
| 核心限制 | 少传 / 多传都会报错 | 1. 避免用列表 / 字典等可变对象做默认值;2. 必须在位置参数后定义 | 调用时需在位置参数之后 | 需在默认参数后、**kwargs前定义 | 必须在参数列表最后定义 | 解包后数量 / 名称需匹配函数定义(否则报错) |
2.2 返回值类型及对比
| 返回值形式 | 核心特点 | 关键注意事项 |
| 无返回值(默认) | 无return,默认返回None | 别误判有 “隐形返回值”,仅执行操作时用 |
| 单个返回值 | 返回单一值,类型不限 | 返回值类型需与调用处预期匹配 |
| 多个返回值 | 本质返回元组,可解包接收 | 解包时变量数量必须与返回值数量匹配(否则报错) |
| 返回容器(列表 / 字典) | 单个容器存储多个值,数量可灵活调整 | 空容器需考虑调用处的空值处理逻辑 |
三.变量作用域
3.1 定义
变量作用域指的是变量在程序中可以被访问、修改的范围。
3.2 类型
3.2.1 全局作用域(Global)
定义:在所有函数外部定义的变量,属于全局作用域。
特点:整个程序运行期间都存在,可被程序中所有函数 “读取”(默认不能直接修改,用 global 关键字声明)。
3.2.2 局部作用域(Local)
定义:在函数内部定义的变量,属于局部作用域。
特点:仅在定义它的函数内部可用,函数执行结束后变量会被销毁,外部无法访问。
3.2.3 非局部作用域(Enclosing)
定义:嵌套函数中,外层函数的变量对于内层函数来说,属于非局部作用域。
特点:内层函数可读取,(默认不能修改,需用 nonlocal 声明)。
3.3 作用域查找规则(LEGB)
L(Local):先找当前函数 / 代码块的局部作用域;
E(Enclosing):如果没找到,找嵌套外层函数的非局部作用域;
G(Global):如果没找到,找全局作用域;
B(Built-in):最后找 Python 内置的变量 / 函数。
四.匿名函数
4.1 本质
临时、简化的函数,无名称,仅实现一行简单逻辑
4.2 语法
# 语法结构:lambda + 参数列表 + : + 单个表达式
lambda 参数1, 参数2, ...: 表达式
4.3 lambda与常见内置函数的使用
4.3.1 lambda + sorted(最常用:自定义排序)
核心作用:指定排序的 “依据”,比如按元组 / 字典的某个值排序
极简语法:sorted(序列, key=lambda x: 排序依据)
e.g.元组列表按第二个元素排序
输入:
data = [(1,5), (4,8), (6,9),(1,7)] print(sorted(data, key=lambda x: x[1]))输出:
4.3.2 lambda + map(批量处理元素)
核心作用:对序列中每个元素执行同一简单操作
极简语法:list(map(lambda x: 处理逻辑, 序列))(转列表才能看到结果)
e.g.提取字典列表的指定字段
输入:
students = [{"name":"张三","age":18}, {"name":"李四","age":16},{"name":"小胡","age":20}] print(list(map(lambda x: x["age"], students)))输出:

4.3.3 lambda + filter(过滤元素)
核心作用:按条件筛选序列中的元素(保留返回 True 的元素)
极简语法:list(filter(lambda x: 过滤条件, 序列))(转列表才能看到结果)
e.g.筛选奇数
输入:
num = [1,2,3,4,5,6,7,8,9,10] print(list(filter(lambda x: x%2==1, num)))输出:

五.嵌套函数
5.1 定义
嵌套函数指的是在一个函数(外部函数)内部定义另一个函数(内部函数)。
5.2 机制
函数调用遵循栈结构,最后被调用的函数最先返回 LIFO (Last In First Out,后进先出)
5.3 应用
- 封装私有逻辑:把仅在主函数内使用的辅助函数嵌套,避免污染全局命名空间;
- 实现闭包:保留外部函数的变量状态;
- 减少参数传递:内部函数可直接用外部函数的变量,无需重复传参。
六.递归函数
6.1 定义
递归函数就是在函数体内调用自身的函数。
必须满足 2 个条件:
基线条件:什么时候停止调用自己(避免无限循环)
递归条件:什么时候调用自己(逐步靠近基线条件)
6.2 递归与循环对比
| 对比维度 | 递归 | 循环 |
| 代码风格 | 简洁、逻辑直观 | 稍繁琐,需手动控制循环变量 |
| 性能 | 有函数调用开销,执行速度稍慢 | 无额外调用开销,执行速度更快 |
| 内存占用 | 占用栈内存,递归深度有限制 | 内存占用稳定,无深度限制 |
| 易错点 | 遗漏基线条件 → 触发无限递归报错 | 遗漏终止条件 → 导致死循环 |
| 适用场景 | 逻辑简单、追求代码简洁时 | 数据量大、追求速度 / 低内存占用时 |
6.3 示例
e.g. 阶乘的计算(简易)
输入:
n = int(input("请输入n的值:")) if n < 0: print("错误:负数没有阶乘!") else: def Factorial(m): if m == 0 or m == 1: return 1 else: return m * Factorial(m - 1) print(f"{n}的阶乘为{Factorial(n)}") 输出: