Python上下文管理器
在代码执行过程中会进行频繁的I/O操作,而计算资源往往是有限的,需要进行资源管理,保证这些资源在使用过后得到释放,防止发生资源泄露。Python中使用上下文管理器(context manager)进行资源管理,比如我们经常用到的 with 关键字,上下文管理器可以进行自动分配并且释放资源。
下面先来介绍一下with关键字在文件读写中的应用,简单了解上下文管理器的功能。 with语句
在Python文件及目录处理方法中介绍了读写大文件建议使用with语句,with语句会进行资源的自动管理。文件很多的情况下也会导致资源泄露,下面来打开100000个文件,不进行文件关闭操作: for x in range(100000): file = open("test.txt", "w") file_descriptors.append(file)
执行会报如下错误: OSError: [Errno 24] Too many open files: "test.txt"
原因就是打开了太多文件而没有及时关闭导致了资源泄露,造成系统崩溃。完成处理后需要对文件进行关闭操作: file_descriptors = [] for x in range(10000): file = open("test.txt", "w") try: file_descriptors.append(file) finally: file.close()
使用 with 语句可以完成自动分配并且释放资源,比上面的写法更加简洁: file_descriptors = [] for x in range(10000): with open("test.txt", "w") as file: file_descriptors.append(file) 上下文管理器创建基于类的上下文管理器
可以使用类来创建上下文管理器,需要保证这个类包括两个方法: __enter__() 和__exit__() 。其中,方法 __enter__() 返回需要被管理的资源,方法 __exit__() 进行资源释放、清理操作。
下面来模拟 Python 的打开、关闭文件操作: class FileManager: def __init__(self, name, mode): print("__init__ method called") self.name = name self.mode = mode self.file = None def __enter__(self): print("__enter__ method called") self.file = open(self.name, self.mode) return self.file def __exit__(self, exc_type, exc_value, exc_traceback): print("__exit__ method called") if self.file: self.file.close() if exc_type: print(f"exc_type: {exc_type}") print(f"exc_value: {exc_value}") print(f"exc_traceback: {exc_traceback}") return True with FileManager("test.txt", "w") as f: print("开始写操作") f.write("hello world !") print(f.closed)
执行结果: __init__ method called __enter__ method called 开始写操作 __exit__ method called exc_type: exc_value: exception raised exc_traceback: True
可以看到执行顺序为: __init__() :初始化对象 FileManager__enter__() :打开文件,返回 FileManager 对象with中的代码 __exit__() :关闭打开的文件流
__exit__() 方法中的参数exc_type , exc_value , 和 exc_traceback 用于管理异常。@contextmanager 装饰器
可以使用 contextlib.contextmanager 装饰器而不使用类的方式来实现上下文管理器,它是基于生成器的上下文管理器,用以支持 with 语句。
仍以打开、关闭文件为例: from contextlib import contextmanager @contextmanager def file_manager(name, mode): try: f = open(name, mode) yield f finally: f.close() with file_manager("test.txt", "w") as f: f.write("hello world !")
其中 file_manager() 函数是一个生成器,yield 之前可以看成是__enter__ 方法中的内容,yield 后面的是 __exit__() 内容。加上@contextmanager 装饰器,使用基于生成器的上下文管理器时,不需要定义__enter__() 和__exit__() 方法。小结
上下文管理器可确保用过的资源得到迅速释放,通常和 with 语句一起使用,大大提高了程序的简洁度。另外需要注意的是,编写基于类或者生成器的上下文管理器时,记住不要忘记释放资源。
--THE END--
社区团购不是一门好生意文孟永辉尽管很多玩家依然在将社区团购看成是重点布局对象,甚至还有持续加码的迹象,但是,作为一种建构在传统流量思维之上的存在,如果社区团购的发展仅仅只是停留在流量的层面上,那么,就注
售1799美元!三星GalaxyZFold35G发布屏占比更高了手机中国新闻8月11日,三星全球新品发布会正式召开!在发布会上我们终于见到了三星的全新折叠屏产品三星GalaxyZFold35G。三星GalaxyZFold35G价格为1799美元
哈啰出行的两款智能助力车单车获北斗检测认证IT之家8月11日消息今日晚间,哈啰出行官方微博发布消息称,哈啰出行的两款产品已经获北斗检测认证。据哈啰出行官方官方介绍,此次获北斗检测的产品为哈啰智能助力车云骑和智能单车白鹿,并
iOS15离线Siri可以做什么?不可以做什么?在没有连接互联网的情况下,使用Siri更快更方便,但您不能用它做所有事情。自苹果推出iOS15以来,目前iOS15软件处于第四个测试阶段,Siri通过新的软件升级获得了一些很棒的功
阿里巴巴与破冰从女员工被侵害说起,有些企业文化破烂到了家今日大舆阿里巴巴与破冰从女员工被侵害说起,有些企业文化破烂到了家船长观舆有些所谓的企业文化破到了家在行为上,是破格在骨子里,是破烂在作用上,是破窗。除了破坏以外,只能暴露企业的破绽
阿里巴巴女员工事件反转了?亚朵酒店突然发声阿里女员工事件又反转了?亚朵酒店突然发声称办理房卡是经过当事女士确认的,这两天阿里女员工事件的爆发引起了全网一阵热议,然而就在所有人以为一切都真相大白之时,事情却突然迎来了反转。针
路过一滩水特斯拉的裤子掉了?网友好家伙4000多没了路过一滩水特斯拉的裤子掉了?网友好家伙4000多没了!震惊!因为一滩水特斯拉裤子掉了,网友调侃4000打水漂了说到新能源汽车,那么大家首先想到的会是哪个汽车品牌呢?如果小编没有猜错
电商大洗牌?淘宝首当其冲,京东却受益满满这几年来,我国的电子商务发展正在进入创新和扩张的新阶段。中国电商的发展非常的迅猛像移动支付,网上购物,物流送货等。以至于有网友玩笑说网购是新的中国四大发明。说到购物软件,有很多人想
天士力副总的儿子让马化腾为阿里女员工发声,态度十分强硬前言2021年7月27日,在阿里的酒局上,一名组长拉着自己的组员进了包间,并且对酒局上的各位领导说道,看我多好,给你们送来一个美女。不过三巡饭过五味,这个送来的美女成为了贡品。美女
关于英伟达数字人文章的致歉和说明大家好,昨天我们发布的一篇英伟达数字人新进展的文章,引发了较大范围的关注和讨论。经过我们的复核及英伟达官方最新确认,这篇文章存在不严谨和失当之处,特此进行说明和致歉。一说明一下我们
支付宝大更新,数字人民币上线近日,看到部分用户的支付宝App中已经加入了数字人民币入口,不过目前仍处于小范围内测,没有入口的小伙伴的可以再等等。数字人民币App更新,钱包运营机构中的网商银行(支付宝)已呈现可