目录
一、上下文管理器
1.1 定义
1.2 特点
1.3 适用场景
1.4 具体实现
1.5 具体实例
1.5.1 文件管理器
1.5.2 线程锁释放资源
二、异步I/O
2.1 定义
2.2 特点
2.3 实现方式
2.4 适用场景
高并发网络服务:Web服务器、API服务等需要处理大量并发连接
2.5 具体实现
2.6 await关键字
三、总结
一、上下文管理器
1.1 定义
上下文管理器(Context Manager)是Python中一种特殊对象,它实现了enter和exit方法,用于在with语句中进行资源管理。它确保在进入和退出代码块时执行特定的初始化和清理操作。
具体实现enter和exit方法的方法:
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
# 使用
with FileManager('example.txt', 'r') as f:
content = f.read()
从具体的实现方式来看,上下文管理器是一种支持 with 语句的对象,用于管理资源(如文件、网络连接等)的获取和释放。
1.2 特点
- 自动资源管理:通过with语句使用,确保资源正确分配和释放
- 异常安全:即使在执行过程中发生异常,也能确保清理代码被执行
- 简洁语法:使用with语句简化代码,提高可读性
- 明确的生命周期:明确定义了进入和退出代码块时的行为
1.3 适用场景
- 文件操作(自动打开和关闭文件)
- 数据库连接管理
- 锁定和解锁资源
- 临时状态更改(如临时改变工作目录)
1.4 具体实现
上面通过enter和exit方法实现只是一种,也能够通过yield在函数中实现
from contextlib import contextmanager@contextmanager
def my_context_manager(message):print(f"Entering context: {message}")try:# yield 之前的代码相当于 __enter__yield messagefinally:# yield 之后的代码相当于 __exit__print(f"Exiting context: {message}")# 使用示例
with my_context_manager("test") as msg:print(f"Inside context with message: {msg}")
1.5 具体实例
1.5.1 文件管理器
class FileManager:def __init__(self, filename, mode):self.filename = filenameself.mode = modeself.file = Nonedef __enter__(self):print(f"Opening file: {self.filename}")self.file = open(self.filename, self.mode)return self.filedef __exit__(self, exc_type, exc_value, traceback):print(f"Closing file: {self.filename}")if self.file:self.file.close()# 处理异常if exc_type is not None:print(f"Exception occurred: {exc_value}")return False # 不抑制异常# 使用示例
with FileManager("test.txt", "w") as f:f.write("Hello, World!")
1.5.2 线程锁释放资源
import threading
# 创建⼀个锁对象,⽤于在多线程中同步对共享资源的访问
lock = threading.Lock()# 定义线程函数,该函数将计数器增加n次
def thread_function(n):global counterfor _ in range(n):# 打印当前线程将计数器增加到的值print(f'线程 {threading.current_thread().name} 将计数器增加到 {counter}')# 获取锁,确保同⼀时间只有⼀个线程在修改counterlock.acquire()try:# 尝试增加计数器counter += 1finally:# 释放锁,允许其他线程进⾏操作lock.release()# 初始化全局计数器
counter = 0
# 初始化线程列表
threads = []# 创建并启动5个线程,每个线程都会执⾏thread_function
for i in range(5):# 创建线程t = threading.Thread(target=thread_function, args=(i,))# 将线程添加到线程列表中threads.append(t)# 启动线程t.start()# 等待所有线程完成执⾏for t in threads:t.join()
# 打印最终的计数器值
print(f'最终的计数器值: {counter}')
二、异步I/O
2.1 定义
异步 I/O(Asynchronous I/O)指发起 I/O 操作后不必等待其完成,内核在后台把数据准备好或写入完成后,再通过回调、事件通知或 Future 等机制通知用户程序;整个过程不会阻塞调用线程,线程可立即转去执行其他任务,从而用极少的线程支撑海量并发。
2.2 特点
-
非阻塞:调用立即返回,线程不挂起
-
事件驱动:完成通知通过回调、Future、epoll、kqueue、IOCP 等事件机制触发。
-
高吞吐、低延迟:单线程即可管理成千上万个并发连接,节省上下文切换和内存开销。
-
编程模型复杂:需要处理回调地狱、状态机、错误传播、背压等问题;现代语言用 Promise/Future/协程/actor 封装。
2.3 实现方式
1.async/await语法:Python 3.5+引入的关键字,用于定义协程函数
2.asyncio库:Python标准库,提供事件循环、协程、任务等核心功能
3.第三方库支持:如aiohttp(HTTP客户端/服务端)、aiomysql(MySQL数据库)等
2.4 适用场景
-
高并发网络服务:Web服务器、API服务等需要处理大量并发连接
- I/O密集型应用:文件操作、数据库查询、网络请求等耗时操作
- 实时数据处理:实时消息处理、流数据处理等
- 爬虫应用:需要同时发起多个网络请求的爬虫程序
2.5 具体实现
基础异步函数:
import asyncio
import timeasync def say_after(delay, what):await asyncio.sleep(delay)print(what)async def main():print(f"started at {time.strftime('%X')}")await say_after(1, 'hello')await say_after(2, 'world')print(f"finished at {time.strftime('%X')}")# 运行异步函数
asyncio.run(main())
2.6 await关键字
Python中async/await的工作原理:
1. async 关键字用于定义一个协程函数,调用协程函数不会立即执行,而是返回一个协程对象
2. await 关键字用于暂停协程的执行,等待另一个协程完成并获取其结果
3. Python的异步IO基于事件循环(Event Loop),事件循环负责调度协程的执行
4. 当遇到 await 表达式时,协程会暂时让出控制权给事件循环,事件循环会去执行其他可执行的协程
5. 当被等待的操作完成后,事件循环会通知原协程继续执行
代码解释:
import asyncioasync def say_after(delay, what):await asyncio.sleep(delay) # 暂停执行delay秒print(what)async def main():print('开始')await say_after(1, 'hello') # 等待1秒后打印helloawait say_after(2, 'world') # 再等待2秒后打印worldprint('结束')# 运行主协程
asyncio.run(main())
在上述代码中,当执行到await asyncio.sleep(delay)时,协程会暂停执行并将控制权交还给事件循环,事件循环可以去执行其他任务。当指定的时间过去后,协程会从暂停的地方继续执行
三、总结
特性 | 上下文管理器 | 异步I/O |
---|---|---|
主要目的 | 资源管理 | 并发执行 |
核心概念 | enter/exit | async/await |
执行模型 | 同步阻塞 | 异步非阻塞 |
资源管理 | 确保资源正确初始化和清理 | 高效处理大量I/O操作 |
异常处理 | 在__exit__中处理 | 通过try/except或任务异常处理 |
性能特点 | 确保资源安全 | 提高并发性能 |
典型应用 | 文件操作、数据库连接 | 网络请求、Web服务器 |
上下文管理器和异步I/O是Python中两种重要的编程机制,它们解决不同层面的问题:
上下文管理器专注于资源管理,确保程序的健壮性和安全性
异步I/O专注于提高程序的并发性能,特别是在I/O密集型场景中
两者可以独立使用,也可以结合使用,共同构建高效、安全的Python应用程序。在现代Python开发中,理解并合理运用这两种机制对编写高质量代码至关重要。