👉 项目官网:https://www.python-office.com/ 👈

👉 本开源项目的交流群 👈

github star gitee star atomgit star

AI编程 AI交流群

大家好,这里是程序员晚枫,正在all in AI编程实战,全网同名。

(3 小时直播脚本 + 课后练习)

──────────────────
0. 开场(5 min)
• 一句话定位:今天之后,你将能“用 Python 的方式”优雅地遍历大文件、流式处理数据,并写出可复用的惰性计算库。
• 课程节奏:45 min 概念 → 30 min 代码实操 → 15 min 调试技巧 → 60 min 综合案例 → 20 min 总结 & 作业 → 10 min Q&A。

──────────────────

  1. 温故:for-loop 背后到底发生了什么?(10 min)
    代码对比:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    lst = [1, 2, 3]
    for x in lst: # 语法糖
    print(x)

    it = iter(lst) # 等价展开
    while True:
    try:
    x = next(it)
    print(x)
    except StopIteration:
    break
    提问:为什么文件对象 open() 可以 for line in f:
    → 引出“迭代器协议”。

──────────────────
2. 迭代器协议解剖(15 min)
2.1 协议定义

  • 可迭代对象:__iter__ 返回迭代器
  • 迭代器对象:__iter__ 返回自身 + __next__StopIteration

2.2 手写一个 Fibonacci 迭代器(现场编码)

1
2
3
4
5
6
7
8
9
10
11
12
13
class Fib:
def __init__(self, n):
self.n, self.a, self.b, self.i = n, 0, 1, 0

def __iter__(self):
return self

def __next__(self):
if self.i >= self.n:
raise StopIteration
self.a, self.b = self.b, self.a + self.b
self.i += 1
return self.a

运行验证:

1
list(Fib(10))

──────────────────
3. 生成器函数:更轻量的迭代器(15 min)
3.1 语法糖

1
2
3
4
5
def fib(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
yield a

对比:代码量 ↓ 80%,状态机由 Python 代管。

3.2 双向通信:send/throw/close
现场演示:

1
2
3
4
5
6
7
def gen():
received = yield 'ready'
yield f'got: {received}'

g = gen()
print(next(g)) # ready
print(g.send(42)) # got: 42

3.3 生成器表达式

1
squares = (x * x for x in range(10**8))  # 惰性

──────────────────
4. 代码实操:重构“逐行读大文件”脚本(30 min)
需求:10 GB 日志文件,提取包含 ERROR 的行并写入新文件。
4.1 原始写法(内存爆炸):

1
2
with open('big.log') as f:
errors = [line for line in f if 'ERROR' in line]

4.2 惰性迭代器版:

1
2
3
4
5
6
7
8
9
def error_lines(path):
with open(path) as f:
for line in f:
if 'ERROR' in line:
yield line

with open('errors.log', 'w') as out:
for line in error_lines('big.log'):
out.write(line)

4.3 进阶:用 itertools.islice 截断前 100 条

1
2
from itertools import islice
first_100 = islice(error_lines('big.log'), 100)

──────────────────
5. 调试技巧:生成器断点 & 可视化(15 min)

  • PyCharm 断点:在 yield 行可单步查看局部变量。
  • reprlib.repr() 打印大对象不卡死。
  • sys.getsizeof 对比列表 vs 生成器内存占用:
    1
    2
    3
    import sys
    sys.getsizeof([x for x in range(1000000)]) # 约 8 MB
    sys.getsizeof((x for x in range(1000000))) # 约 120 B

──────────────────
6. 综合案例:实时日志监控器(60 min)
需求:对持续写入的日志文件,实时输出 ERROR 行并统计数量。
技术栈:生成器 + tail -f 模拟 + asyncio(预告下一章)。
6.1 实现 tail 生成器

1
2
3
4
5
6
7
8
9
10
import time
def tail(path):
with open(path) as f:
f.seek(0, 2) # 跳到末尾
while True:
line = f.readline()
if not line:
time.sleep(0.1)
continue
yield line

6.2 聚合统计

1
2
3
4
5
6
from collections import Counter
counts = Counter()
for line in tail('app.log'):
if 'ERROR' in line:
counts['error'] += 1
print(line.strip(), counts['error'])

6.3 打包成 CLI 工具(typer 快速演示,为第 9 章埋点)。

──────────────────
7. 总结 & 思维导图(5 min)
迭代器协议 → 生成器函数 → 惰性计算 → 内存友好 → 流式架构。

──────────────────
8. 课后练习

  1. 必做:把今天的 tail 生成器改成支持 gzip 压缩日志(提示:gzip.open 也实现了迭代器协议)。
  2. 选做:用生成器写一个“无限滑动平均”函数,输入任意数字序列,输出实时平均。
  3. 思考题:为什么 list(iterator) 会耗尽迭代器?如何实现“可重置”的迭代器?

提交方式:

  • 代码 push 到 GitHub Classroom 指定仓库;
  • CI 会自动跑测试 & 内存基准测试(使用 pytest-benchmark)。

──────────────────
9. 下集预告
第 2 章装饰器:把今天的 tail 监控器加上 @retry@rate_limit 等可插拔能力。

(完)


大家在学习课程中有任何问题,欢迎+微信和我交流👉我的联系方式:微信、读者群、1对1、福利

扫一扫,领红包

美团红包

程序员晚枫专注AI编程培训,小白看完他和图灵社区合作的教程《30讲 · AI编程训练营》就能上手做AI项目。

🎓 AI 编程实战课程

想系统学习 AI 编程?程序员晚枫的 AI 编程实战课 帮你从零上手!