☰
Python第三天
2026/10/14 3:32:54 网站建设 项目流程

函数

语法骨架

def 函数名(参数1, 参数2, ...):
"""文档字符串(可选,说明函数作用)"""
函数体
return 返回值 # 可选,没有 return 则返回 None

函数整体的解释

┌──────────────────────────────────────────────────────┐
│ 函数的四要素 │
├──────────────────────────────────────────────────────┤
│ 1. 函数名 → 怎么叫它(见名知意,snake_case) │
│ 2. 参数 → 输入(可无) │
│ 3. 函数体 → 干什么(缩进代码块) │
│ 4. 返回值 → 输出(用 return,可无) │
└──────────────────────────────────────────────────────┘

参数

位置参数和关键字参数

默认参数(缺省参数)

*args和**kwargs(不定长参数)

*args:接收任意多个位置参数

参数解读:

*args— 星号把调用时传进来的多个位置参数收集成一个元组args。my_sum(1,2,3,4)里args=(1,2,3,4)。这样函数就能接收"不确定个数"的参数

**kwargs:接收任意多个关键字参数

参数解读:

**kwargs— 双星号把多个key=value收集成一个字典kwargs。适合"参数名不固定"的场景(如配置项)

调用时的参数解包

需求:已经有了一个列表[1,2,3]和一个字典{"a":1},想直接把它们"拆开"当成参数传给函数,而不是一个个手写。

分析:在调用函数时,*把序列(列表/元组)拆成位置参数,**把字典拆成关键字参数。注意:这和解包赋值(a, b = [1, 2])不是一回事,这里专指"传参时解包"。

步骤:新建代码/day03_unpack_args.py:

递归

需求:有些问题"自己定义自己"更自然,比如"n 的阶乘 = n × (n-1) 的阶乘"。这种"函数内部调用自己"就是递归。

分析:递归要满足三要素,缺一不可:

  1. 结束条件(终止条件):最小的情况直接给结果,不再递归,否则无限循环。

  2. 递推关系:大问题拆成更小的同类问题(调用自己)。

  3. 向结束条件递进:每次递归都要让参数"更接近"基线,否则永远到不了终止条件。

第一个案例(求5的阶乘)

第二个案例(斐波那契数列)

# 1 1 第三个数开始是前两个数之和
# 1 1 2 3 5 8 13 21 34 ...
# 定义一个函数 求第n个斐波那契数列的数
# 使用递归
# 1.必须让递归有一个结束条件
# 2.找规律调用自己(重点!!!!!)
# 3.向结束条件逼近

总结

┌──────────────────────────────────────────────┐
│ 递归三要素: │
│ ① 基线条件:最小情况,直接返回 │
│ ② 递推关系:拆成更小的同类问题 │
│ ③ 向基线收敛:参数越来越接近基线 │
│ 风险:缺基线/不收敛 → 栈溢出 RecursionError │
└──────────────────────────────────────────────┘

作用域

全局变量

┌──────────────────────────────────────────────────┐
│ 全局变量:函数外部定义,整个文件都能用 │
│ 函数内想修改它,必须加 global 声明 │
└──────────────────────────────────────────────────┘

nonlocal 关键字

需求:内层函数默认改不了外层嵌套变量。如果确实要改(比如做计数器),怎么办?用nonlocal。

分析:nonlocal与global容易混,区别如下:

关键字作用对象使用场景
global文件顶层的全局变量在函数里改全局变量
nonlocal外层(非全局)嵌套函数里的变量在更内层函数里改外层函数的变量

nonlocal只能用于嵌套函数,且必须在修改前声明。

lanbda(匿名函数)

lambda是"匿名函数",适合写只有一行逻辑的小函数。

公式:lambda 参数:表达式

闭包和装饰器

闭包

需求:有个外层变量count,函数执行完本该被销毁;但我希望"函数结束后,内层函数还能记住并修改这个外层变量"——这就是闭包要解决的。

分析:闭包 = 带着"环境背包"的函数。它必须同时满足三个条件(缺一不可):

┌──────────────────────────────────────────────────────┐
│ 闭包三大条件 │
├──────────────────────────────────────────────────────┤
│ ① 函数嵌套:内层函数定义在外层函数内部 │
│ ② 变量引用:内层函数引用了外层函数的变量(非全局) │
│ ③ 返回内层函数:外层函数 return 内层函数本身 │
└──────────────────────────────────────────────────────┘

闭包的核心价值:把"状态"保存下来。外层函数结束后,内层函数依然"背着"当时的外层变量,每次调用都能累积。

预期效果:

命令 / 代码参数解读

  • return counter— 注意没有括号,返回的是函数对象本身,不是调用结果。所以c1 = create_counter()拿到的是一个"记住了count=0"的函数。

  • c1()每次调用,counter里的nonlocal count修改的是那个被记住的外层count,于是不断累加:1 → 2 → 3。

  • c2是另一次create_counter()创建的,有自己独立的count,所以c2()又从 1 开始。

  • c1.__closure__是一个元组,装着闭包捕获的每个外层变量("cell");cell_contents就是它当前的值3。

小结:

闭包 = 内层函数 + 它记住的外层变量。常见用途:计数器、配置缓存、装饰器底层。

装饰器(传统&@语法糖)

需求:已有十几个函数,现在想给它们统一加上"执行前打印日志 / 计时"的功能,但不想改这些函数本身的代码(开闭原则:对扩展开放、对修改关闭)。

传统

语法糖

扩展知识点:

sort:对列表内的数据进行排序

sorted&reverse:排序&反转顺序

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询