Python中上下文管理器有何作用,创建方法是什么
Admin 2022-06-23 群英技术资讯 449 次浏览
在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: <class 'Exception'>
exc_value: exception raised
exc_traceback: <traceback object at 0x000001B43C2444C8>
True
可以看到执行顺序为:
__init__()
:初始化对象 FileManager__enter__()
:打开文件,返回 FileManager 对象with中的代码
__exit__()
:关闭打开的文件流
__exit__()
方法中的参数exc_type, exc_value, 和 exc_traceback 用于管理异常。
可以使用 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__()
方法。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
如何理解Python中if语句,语法是什么?下文的讲解详细,步骤过程清晰,对大家进一步学习和理解相关知识有一定的帮助。有这方面学习需要的朋友就继续往下看吧!
这篇文章主要介绍了Python变量名详细规则详细变量值,Python需要使用标识符给变量命名,其实标识符就是用于给程序中变量、类、方法命名的符号(简单来说,标识符就是合法的名称,下面葛小编一起进入文章里哦阿姐更多详细内容吧
在Python项目中,获取了接口返回的json数据,然后按行读取所有数据,把想着数据写到txt时,中文总显示例如: u'\u4e5d\u52a9\u5e55\的问题怎么办
这篇文章主要给大家分享的是关于pytorch中使用cuda处理数据的内容,小编认为比较实用,因此分享给大家作参考,下文有具体的方法和实例,感兴趣的朋友跟随小编一起来了解一下吧。
这篇文章主要介绍了关于python中range()的参数问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008