摘要: 本文是作为计算机专业学生在学习Python高级特性时的详细笔记。文章首先简要回顾了作用域、闭包与装饰器的核心概念,随后深入探讨了函数递归、各类推导式的优雅写法、生成器与迭代器的内存管理机制,以及Python包与模块的导入与管理。旨在通过系统的梳理,打通Python进阶路上的关键节点。


上节课回顾:作用域、闭包与装饰器

在进入今天的新内容之前,我们先快速复盘一下Python函数式编程的三大基石,它们是理解后续高级特性的基础:

  1. 作用域 (Scope): Python遵循 LEGB 原则查找变量,即从局部作用域 (Local) -> 嵌套作用域 (Enclosing) -> 全局作用域 (Global) -> 内置作用域 (Built-in)。理解作用域是理解变量生命周期的关键。
  2. 闭包 (Closure): 当一个内部函数引用了外部函数的变量,并且外部函数返回了这个内部函数时,就形成了闭包。闭包让数据可以“私有化”并长期驻留在内存中。
  3. 装饰器 (Decorator): 装饰器本质上是一个返回函数的高阶函数(通常利用闭包实现)。它允许我们在不修改原函数代码的前提下,动态地为函数添加额外的功能(如日志、计时、权限校验)。
一、 函数递归:在函数中调用自己

1. 什么是递归?
递归函数是指在函数内部调用自身的函数。它包含了一种隐式的循环,不需要显式的循环条件控制,但必须包含两个核心要素:

  • 临界条件(结束条件): 防止无限循环,避免栈溢出。
  • 递推关系(公式): 找到相邻两次调用之间的规律。

2. 核心案例分析

  • 阶乘计算: n! = n * (n-1)!,临界值为 1! = 1。
  • 斐波那契数列: f(m) = f(m-1) + f(m-2),临界值为第1、2个数均为1。

代码演示:

# 计算 n 的阶乘
def factorial(n):
    if n == 1:  # 临界条件
        return 1
    else:
        return n * factorial(n-1)  # 递推关系

print(factorial(5))  # 输出: 120

# 计算第 m 个斐波那契数
def fibonacci(m):
    if m <= 2:
        return 1
    else:
        return fibonacci(m-1) + fibonacci(m-2)

print(fibonacci(6))  # 输出: 8

💡 学习心得: 递归虽然代码简洁,逻辑清晰,但在实际项目中要慎用。因为Python默认的递归深度限制约为1000次,过深的递归会导致栈溢出(Stack Overflow)或内存泄漏。


二、 推导式:一行代码的优雅

推导式是Python中一种非常Pythonic的创建容器的方式,它能让代码更加简洁。

1. 列表推导式 (List Comprehension)
用于快速生成列表。基本语法:[表达式 for 变量 in 可迭代对象 if 条件]

2. 字典与集合推导式
与列表推导式类似,只是符号换成了 {}

代码演示:

# 列表推导式:生成1-10的平方
squares = [i ** 2 for i in range(1, 11)]
print(squares)  # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

# 带条件的推导式:筛选1-10中的偶数
evens = [i for i in range(1, 11) if i % 2 == 0]
print(evens)  # [2, 4, 6, 8, 10]

# 字典推导式:创建数字与其平方的映射
square_dict = {i: i ** 2 for i in range(1, 6)}
print(square_dict)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# 集合推导式:去重并生成集合
unique_squares = {i ** 2 for i in [1, 2, 2, 3, 3, 3]}
print(unique_squares)  # {1, 4, 9}

代码运行结果如图:


三、 生成器与迭代器:内存管理的艺术

1. 生成器 (Generator)
生成器是一种特殊的迭代器,它不会一次性将所有数据加载到内存中,而是按需生成数据,非常适合处理大量数据或无限序列。

  • 创建方式: 将列表推导式的 [] 改为 ()
  • 生成器函数: 使用 yield 关键字。yield 类似于 return,但不会终止函数,而是暂停函数并在下次调用时从暂停处继续执行。

2. 迭代器 (Iterator)

  • 可迭代对象 (Iterable): 能被 for 循环遍历的对象(如 list, tuple, str, dict, generator)。
  • 迭代器 (Iterator): 既能被 for 遍历,又能被 next() 函数调用的对象。生成器是迭代器的一种。

代码演示:

# 1. 生成器表达式
g = (i for i in range(1, 4))
print(g)  # <generator object>
print(next(g))  # 1

代码运行结果如图:

我们可以发现,单纯使用print()函数打印出来的是告诉你这个是生成器对象,然后打印出来它的16进制内存地址。只有用next()才能调用打印这个生成器表达式。

# 2. 生成器函数 (斐波那契数列生成器)
def fib_generator():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

f = fib_generator()
# 获取前5个斐波那契数
for _ in range(5):
    print(next(f), end=' ')  # 0 1 1 2 3

代码运行结果如图:

同理,生成器函数也是如此,需要用next()来调用。


四、 模块与包:代码的组织与复用

随着项目规模变大,将所有代码写在一个文件里是不可维护的。Python通过模块(Module)和包(Package)来组织代码。

1. 模块 (Module)
一个 .py 文件就是一个模块。模块分为三类:

  • 内置模块: Python自带(如 os, time, random)。
  • 自定义模块: 自己写的 .py 文件。
  • 第三方模块: 别人写的(如 numpy, requests)。

2. 包 (Package)
包含 __init__.py 文件的文件夹称为包。它用于管理多个相关的模块。

3. 导入方式

  • import module:导入整个模块。
  • from module import function:精确导入,避免命名冲突。
  • import module as alias:使用别名。

4. 第三方包管理
使用 pip 工具进行管理。国内推荐使用镜像源加速安装。

代码演示:

# 导入方式示例
import time
from random import randint
import numpy as np  # 使用别名

# 常用pip命令 (在终端执行)
# pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple  # 临时换源安装
# pip freeze > requirements.txt  # 导出当前环境依赖
# pip install -r requirements.txt  # 根据文件安装依赖

五、 总结与反思

通过这次学习,我深刻理解了Python中几个核心的高级特性:

  1. 递归 是一种分治思想,虽然好用但要注意性能和深度限制。
  2. 推导式 让代码变得极其简洁,但在可读性和简洁性之间需要权衡,过于复杂的推导式反而难以维护。
  3. 生成器 是Python的内存优化利器,利用 yield 实现了“按需计算”,在处理大数据流时非常有用。
  4. 模块化 是工程化的基础,合理的包结构能让项目井井有条。

未来的学习计划: 接下来我将开始面向对象编程的学习,继续夯实Python基础。

Logo

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

更多推荐