上下文管理器和异步I/O

目录

一、上下文管理器

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. 文件操作(自动打开和关闭文件)
  2. 数据库连接管理
  3. 锁定和解锁资源
  4. 临时状态更改(如临时改变工作目录)

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关键字

Pythonasync/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/exitasync/await
执行模型同步阻塞异步非阻塞
资源管理确保资源正确初始化和清理高效处理大量I/O操作
异常处理在__exit__中处理通过try/except或任务异常处理
性能特点确保资源安全提高并发性能
典型应用文件操作、数据库连接网络请求、Web服务器

上下文管理器和异步I/O是Python中两种重要的编程机制,它们解决不同层面的问题:
        上下文管理器专注于资源管理,确保程序的健壮性和安全性
        异步I/O专注于提高程序的并发性能,特别是在I/O密集型场景中


两者可以独立使用,也可以结合使用,共同构建高效、安全的Python应用程序。在现代Python开发中,理解并合理运用这两种机制对编写高质量代码至关重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/922356.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/922356.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW信号监测与分析

借助 LabVIEW 平台,生成含正弦波与噪声的信号,经频谱分析等处理,结合动态限值判断信号是否超限,广泛用于音频、振动等领域的信号监测,助力高效开展信号分析与质量把控。概念说明系统围绕信号的生成、处理、分析及监测展…

MySQL数据库与表的创建、修改及数据操作指南

精选专栏链接 🔗 MySQL技术笔记专栏Redis技术笔记专栏大模型搭建专栏Python学习笔记专栏深度学习算法专栏 欢迎订阅,点赞+关注,每日精进1%,与百万开发者共攀技术珠峰 更多内容持续更新中!希望能给大家带来…

​new species of flying reptile1 discovered in Scotland​

Pterosaur: new species of flying reptile1 discovered in Scotland 苏格兰斯凯岛发现新翼龙物种 考古学家们在苏格兰斯凯岛发现了一个新的翼龙物种。这种独特的飞行爬行动物生活在1.68 – 1.66亿年前。 This flying reptile soared over the heads of dinosaurs2 when Scotla…

03 节点行为

审批流程图如下图,在此流程图中,存在两个UserTask节点,第一个节点是主管审批,第二个节点是产品经理审批,两个节点中间有一个排他网关,此网关用来对主管审批的结果进行判断,如果主管审批通过&…

深度卷积生成对抗网络详解与实现

深度卷积生成对抗网络详解与实现 0. 前言 1. 网络架构 1.1 批归一化 1.2 激活 1.3 上采样 2. 构建 DCGAN 2.1 生成器 2.2 判别器 2.3 训练 DCGAN 0. 前言 深度卷积生成对抗网络 (Deep Convolutional Generative Adversarial Network, DCGAN) 是基于生成对抗网络 (Generative A…

CF607B Zuma -提高+/省选-

CF607B Zuma codeforces 原链接 题目描述 Genos\texttt{Genos}Genos 最近在他的手机上下载了祖玛游戏。在祖玛游戏里,存在 nnn 个一行的宝石,第 iii 个宝石的颜色是 CiC_iCi​。这个游戏的目标是尽快的消灭一行中所有的宝石。 在一秒钟,Ge…

拆分了解HashMap的数据结构

文章目录 前言 一、底层数据结构总览 二、核心组成部分详解 1. 数组(哈希表) 2. 节点(Node) 3. 红黑树(TreeNode) 三、哈希函数与索引计算 四、哈希冲突的解决 五、扩容机制 六、关键特性与注意事…

关于电脑连接不到5g的WiFi时的一些解决办法

方法一、设备管理器重卸载驱动后,重装驱动。方法二、打开控制面板 “控制面板\网络和 Internet\网络连接” (亲测有效)点击更改适配器配置右击当前的WLAN属性点击配置选择“高级” 802.11a/b/g 无线模式选项栏 值:6.的双…

Mathtype公式批量编号一键设置公式居中编号右对齐

插件[ygtools] 批量编号一键设置公式居中编号右对齐 单栏/多栏均可https://wwon.lanzout.com/i0NRf35vyw8j 下载密码8543

基于ssm的小橘子出行客户体验评价系统[SSM]-计算机毕业设计源码+LW文档

摘要:随着出行行业的快速发展,客户体验评价对于出行服务质量的提升至关重要。本文设计并实现了基于SSM(Spring Spring MVC MyBatis)框架的小橘子出行客户体验评价系统。该系统涵盖系统用户管理、司机信息管理、客户评价管理等功…

算法日记---二分查找

目录 前言 一、二分查找 1.思想 2.简单二分 3.优点 4.局限性 二、模板 1.基本模板 2.简单例题(LeetCode) 4.有重复元素的二分 5.0-1问题 总结 前言 本文通过讲解简单的二分查找配合leetcode例题对二分查找本质、模板进行了基础的总结 提示&a…

Level Set(水平集)算法——形象化讲解

目录 维度一:核心思想与比喻(它像什么?) 维度二:要解决什么问题?(它能干嘛?有什么用?) 维度三:工作原理(它是怎么做到的&#xff1…

DDoS 攻防“军备竞赛”的幕后

谈到 DDoS(分布式拒绝服务攻击),很多人会想到“黑客租用肉鸡发流量,网站直接崩”。但事实上,如今的 DDoS 攻防早已变成一场 军备竞赛。攻击者的武器越来越“工业化”:僵尸网络商品化:黑市上&…

如何用 Rust 重写 SQLite 数据库(二):是否有市场空间?

用 Rust 实现一个类似 SQLite 的嵌入式数据库非常有意义,但需要结合具体目标和场景来评估其价值。以下从技术、生态、市场需求和个人成长等多个维度展开分析,并给出结论。一、技术价值:Rust 与数据库的天然契合 SQLite 作为全球装机量最大的数…

【Web】ImaginaryCTF 2025 wp

目录 imaginary-notes certificate codenames-1 passwordless pearl imaginary-notes I made a new note taking app using Supabase! Its so secure, I put my flag as the password to the "admin" account. I even put my anonymous key somewhere in the si…

oracel如何找到外键子表

要找到导致外键约束冲突的子表(即包含"child record"的表),可以通过以下SQL查询在Oracle数据库中定位:1. 查询约束基本信息(确定父表和子表)SELECT owner, constraint_name, table_name AS child…

智源研究院新研究:突破物理世界智能边界的RoboBrain 2.0,将重构具身AI能力天花板

当你对着家用机器人说"把杯子放在笔筒和键盘之间,对齐杯身logo"时,它能精准理解空间关系并执行动作;当多台机器人在超市协作补货时,它们能自主规划轨迹、避免冲突并完成长周期任务——这些曾经出现在科幻电影中的场景&a…

【2025】Office核心组件Microsoft word,Excel,PowerPoint详细使用指南

Office 核心组件使用指南 Microsoft Word 文字处理 Word主要用于创建和编辑文档,如信件、报告、论文等。 2025Office🔗 1. 界面认识 快速访问工具栏:位于左上角,可自定义保存、撤销、恢复等常用命令。功能区:顶部…

【模型训练篇】VeRL的使用 - RL(PPO)与源码

继续学习字节家的VeRL,今天来看看VeRL的RL,是VeRL系列的第三篇文章(话说近期好多大事儿,我司发布了Longcat、韩立结婴、阿里周五发布了QWen-Next都是好东西啊,学不过来了damn) 底层分布式能力基础Ray&…

QML Charts组件之折线图的鼠标交互

目录前言相关系列代码示例详解(LineSeriesDemo3.qml)功能概览运行效果代码说明工程下载参考前言 接上文(QML Charts组件之折线图的基础属性),本文将重点介绍LineSeries的鼠标交互,包括:鼠标拖拽…