Files
2026-06-15 00:55:47 -06:00

55 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 天气数据自动采集与推送系统——异步编程优化与协程调度 教学设计
| **课题** | **天气数据自动采集与推送系统——异步编程优化与协程调度** |
|---------|------------------------------------------|
| **课时** | 1课时(40分钟) |
| **教学目标** | **知识目标**理解同步与异步编程的区别掌握Python协程(coroutine)的基本概念了解asyncio事件循环的工作原理理解async/await语法的作用。<br>**技能目标**能够使用async/await语法定义异步函数能够使用asyncio库实现异步HTTP请求能够将项目的同步代码改造为异步版本以提升性能能够使用asyncio.gather()并发执行多个协程任务。<br>**素养目标**:建立"非阻塞"的高性能编程思维理解异步编程在I/O密集型场景中的优势培养性能优化与代码重构能力。 |
| **教学重难点** | **重点**async/await语法的使用方法asyncio事件循环的启动与任务调度aiohttp库的异步HTTP请求asyncio.gather()的并发执行机制。<br>**难点**:理解协程与线程的本质区别;掌握异步函数的调用方式(不能直接调用);处理异步代码中的异常;设计合理的异步任务协作模式。 |
| **教学资源准备** | 多媒体课件含同步vs异步对比动画、事件循环机制图前期完成的同步版天气采集代码aiohttp库安装包异步性能对比测试脚本asyncio编程示例代码。 |
## 教学过程
| 教学环节 | 教学内容 | 教师活动 | 学生活动 | 设计意图 |
|:---------|:---------|:---------|:---------|:---------|
| **1. 性能优化需求**<br>(6分钟) | 回顾多线程方案的局限性GIL限制、线程开销引出异步编程作为I/O密集型任务的更优解决方案明确本课时要用异步优化项目性能。 | **问题引入**<br>回顾第2课时的多线程方案提问"线程切换有开销,有没有更轻量的并发方式?"说明Python的GIL限制了多线程的CPU利用率<br><br>**方案对比**<br>展示对比图多线程抢占式调度、线程开销大vs 异步协作式调度、轻量级协程强调异步适合网络I/O场景。 | **回顾反思**<br>回忆多线程实现,思考其局限性,理解"等待网络响应时线程空闲"的资源浪费;<br><br>**需求明确**<br>理解本课时目标:用异步编程替代多线程,实现更高效的并发采集。 | 通过问题引入建立技术演进认知;通过方案对比帮助学生理解异步的适用场景,明确优化目标。 |
| **2. 异步编程原理**<br>(8分钟) | 讲解协程、事件循环、async/await的基本概念演示简单的异步函数定义与调用说明异步编程的执行模型。 | **概念讲解**<br>用餐厅类比:同步是服务员一桌服务完再服务下一桌,异步是服务员在等待上菜时去服务其他桌;说明协程是"可暂停的函数"await是"暂停点"<br><br>**语法演示**<br>演示async/await基础<br>```python<br>import asyncio<br>async def hello():<br> print("开始")<br> await asyncio.sleep(2)<br> print("结束")<br>asyncio.run(hello())<br>```<br>讲解async定义异步函数、await等待异步操作、asyncio.run()启动事件循环;<br><br>**原理说明**<br>展示事件循环图遇到await时切换到其他协程I/O完成后切回继续执行。 | **聆听理解**<br>理解"协作式调度"的思想记录async/await是异步编程的核心语法<br><br>**代码跟随**<br>输入演示代码并运行观察异步函数的执行过程尝试创建多个协程用asyncio.gather()并发运行;<br><br>**原理认知**<br>理解事件循环是异步任务的"调度器"await是"主动让出控制权"的标记。 | 通过类比降低异步概念难度通过简单示例建立async/await的基本使用模式通过原理图帮助学生理解异步调度机制。 |
| **3. 异步HTTP请求**<br>(12分钟) | 介绍aiohttp库演示使用aiohttp实现异步天气数据获取指导学生将同步的requests代码改造为异步版本。 | **库的引入**<br>说明requests是同步库aiohttp是异步HTTP客户端库演示安装pip install aiohttp<br><br>**代码改造**<br>对比演示同步与异步代码:<br>```python<br># 同步版本<br>response = requests.get(url, params=params)<br>data = response.json()<br><br># 异步版本<br>async with aiohttp.ClientSession() as session:<br> async with session.get(url, params=params) as response:<br> data = await response.json()<br>```<br>讲解ClientSession管理连接池、async with上下文管理、await response.json()等待解析;<br><br>**并发实现**<br>演示用asyncio.gather()并发请求多城市:<br>```python<br>tasks = [fetch_weather(city) for city in cities]<br>results = await asyncio.gather(*tasks)<br>```<br><br>**性能测试**<br>运行异步版本对比同步和多线程的耗时如从15秒→3秒→1秒。 | **对比学习**<br>对比同步与异步代码的差异,理解"async with"和"await"的作用;<br><br>**功能改造**<br>创建async_weather_fetcher.py定义异步的fetch_weather()函数使用aiohttp实现<br><br>**并发实现**<br>编写主函数用asyncio.gather()并发请求10个城市用time模块测量耗时<br><br>**性能验证**<br>运行代码,记录耗时数据,对比同步、多线程、异步三种方案的性能差异。 | 通过对比教学强化同步与异步的区别;通过代码改造巩固异步编程技能;通过性能测试建立"异步更快"的直观认知。 |
| **4. 项目集成优化**<br>(10分钟) | 指导学生将异步采集模块集成到项目主程序,讨论异步定时任务的实现方式,处理异步代码中的异常与日志。 | **集成方案**<br>说明如何在定时任务中调用异步函数:<br>```python<br>def job():<br> asyncio.run(async_fetch_all())<br>schedule.every(30).minutes.do(job)<br>```<br>或使用asyncio自带的定时功能<br><br>**异常处理**<br>演示异步代码的try-except写法与asyncio.gather()的return_exceptions参数<br><br>**实践指导**<br>引导学生改造main_scheduler.py将并发采集改为异步版本添加异常处理与日志。 | **理解方案**<br>理解如何在同步代码中启动异步任务记录asyncio.run()的桥接作用;<br><br>**代码优化**<br>修改主程序,集成异步采集模块,测试定时任务是否正常触发;<br><br>**完善细节**<br>添加异步异常处理,确保单个城市请求失败不影响其他城市;测试异常情况(如断网)。 | 通过集成实践强化异步在真实项目中的应用;通过异常处理培养健壮性意识;通过完整测试验证优化效果。 |
| **5. 技术对比与总结**<br>(4分钟) | 总结同步、多线程、异步三种方案的适用场景,回顾整个项目的技术演进路径,展望异步编程的应用前景。 | **技术对比**<br>总结三种方案同步简单但慢、多线程适合I/O密集但有开销、异步最高效但学习曲线陡强调选择技术要看场景<br><br>**项目回顾**<br>梳理项目的技术升级HTTP请求→多线程并发→异步优化体现"迭代优化"的工程思维;<br><br>**任务布置**<br>课后任务阅读asyncio官方文档尝试用异步实现TCP服务器asyncio.start_server。 | **总结反思**<br>对比三种方案的特点,理解"没有银弹"的技术选型原则;<br><br>**项目总结**<br>回顾整个学习历程,体会从基础功能到性能优化的完整开发流程;<br><br>**接收任务**<br>记录课后任务理解异步编程的应用不限于HTTP请求。 | 通过技术对比培养技术选型能力;通过项目回顾强化系统化学习成果;课后任务拓展异步应用视野。 |
## 板书设计
```
异步编程模型对比
同步执行(阻塞):
任务1 ━━━━━━━━┓
┗━━━━━━━━ 任务2 ━━━━━━━━┓
┗━━━━━━━━ 任务3
总耗时 = T1 + T2 + T3
异步执行(非阻塞):
任务1 ━━━━ await ━━━━ 完成
任务2 ━━━━ await ━━━━ 完成
任务3 ━━━━ await ━━━━ 完成
总耗时 ≈ max(T1, T2, T3)
核心语法:
async def func(): # 定义异步函数
result = await ... # 等待异步操作
asyncio.run(func()) # 启动事件循环
asyncio.gather(*tasks) # 并发执行多任务
性能对比 (10城市采集):
同步: 15秒
多线程: 3秒
异步: 1秒
```
## 教学成效与反思
| | |
|:---|:---|
| **教学成效** | 结合本课时项目任务评估80%学生成功使用async/await语法实现异步天气采集75%学生能够用asyncio.gather()实现并发请求。通过性能对比实验15秒→3秒→1秒学生对异步编程的价值有了震撼性认知学习热情高涨。异步编程虽是本课程难点但通过餐厅服务员类比、同步异步代码对比、性能数据说话等多种教学手段大部分学生能够理解核心概念并基本掌握。项目的最终版本已实现异步优化整体性能提升显著。部分学生在理解"协程切换"与"事件循环"机制时有困难,但通过可视化图示和反复演示得以缓解。 |
| **教学反思** | 本课时成功将"异步编程"这一Python高级特性转化为"极致优化天气采集性能"的具体任务,学习动机强烈。技术演进的叙事线索(同步→多线程→异步)设计合理,让学生理解"为什么需要异步"而非"为了学而学"。性能对比实验的说服力强数据直观震撼。餐厅类比和事件循环可视化有效降低了抽象概念难度。不足之处①在40分钟内异步编程的深层机制如事件循环的底层实现、协程调度细节无法深入部分学生可能停留在"会用但不深懂"的层面,建议提供补充阅读材料;②对"何时应该使用异步"的判断标准讲解不足,少数学生可能产生"异步万能"的误解建议明确说明CPU密集型任务不适合异步③aiohttp的连接池管理、超时设置等高级特性未涉及实际生产应用还需补充④课后任务的难度较大异步TCP服务器可能导致完成率低建议降低难度或提供详细提示。整体上异步编程课程作为项目的"性能巅峰"有效展示了Python在高并发场景中的强大能力五节课形成的完整技术栈HTTP→多线程→定时→TCP→异步具有很强的系统性和实战价值教学目标超预期达成。建议在后续教学中可将本项目作为综合实训案例的"标准版"引导学生在此基础上扩展更多功能如数据库持久化、Web界面、数据分析可视化等。 |