深人了解Python上下文管理器

目录
  • with语句
  • 上下文管理器创建
    • 基于类的上下文管理器
    • @contextmanager 装饰器
  • 总结

下面先来介绍一下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: <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 用于管理异常。

@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--

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Python实现上下文管理器的方法

    问题 你想自己去实现一个新的上下文管理器,以便使用with语句. 解决方案 实现一个新的上下文管理器的最简单的方法就是使用 contexlib 模块中的 @contextmanager 装饰器. 下面是一个实现了代码块计时功能的上下文管理器例子: import time from contextlib import contextmanager @contextmanager def timethis(label): start = time.time() try: yield finally:

  • Python上下文管理器全实例详解

    Python上下文管理器 简介 最近用到这个,仔细了解了一下,感觉是十分有用的,记录一下 使用场景 当我们需要获取一个临时打开的资源,并在使用完毕后进行资源释放和异常处理,利用try-catch语句可以完成,举个例子. 打开文件: f = None try: print("try") f = open("__init__.py", "r") print(f.read()) except Exception as e: print("ex

  • 详解python with 上下文管理器

    作为一个 Java 为母语的程序员来讲,学习起其他新的语言就难免任何事都与 Java 进行横向对比.Java 7 引入了能省去许多重复代码的 try-with-resources 特性,不用每回 try/finally 来释放资源(不便之处有局部变量必须声明在 try 之前,finally 里还要嵌套 try/catch 来处理异常).比如下面的 Java 代码 try(InputStream inputStream = new FileInputStream("abc.txt"))

  • Python上下文管理器Content Manager

    在 Python 中,我们会经常听到上下文管理器(Context Manager),那我们探讨下这是什么,又有什么功能. 在 Python 中的上下文管理器中,使用 with 打开文件是使用最多的,其中离开 with 包含的语句后会执行一些类似于清理的工作,如关闭文件,关闭连接对象等操作. 实践 我们在代码实践的时候,忽略了在同一代码片段中,先打开文件,然后直接对文件进行其他处理,因为这样没有任何意义,资源是处于被占用的情况. 先看下面检测的代码: #!/usr/bin/env python #

  • Python上下文管理器实现方法总结

    目录 什么时候可以考虑上下文管理器 方法1(上下文管理器协议) 方法2(@contextmanager) 方法3(contextlib.closing()) 什么时候可以考虑上下文管理器 当你的代码逻辑需要用到如下关键字时,可以考虑使用上下文管理器让你的代码更加优雅: try: ... finally: ... 接下来介绍实现上下文管理器的三种方法. 方法1(上下文管理器协议) 总所周知,open()是默认支持上下文管理器的.所以打开一个txt文件,并向里面写入内容,再关闭这个文件的代码可以这样

  • 深人了解Python上下文管理器

    目录 with语句 上下文管理器创建 基于类的上下文管理器 @contextmanager 装饰器 总结 下面先来介绍一下with关键字在文件读写中的应用,简单了解上下文管理器的功能. with语句 在Python文件及目录处理方法中介绍了读写大文件建议使用with语句,with语句会进行资源的自动管理.文件很多的情况下也会导致资源泄露,下面来打开100000个文件,不进行文件关闭操作: for x in range(100000): file = open('test.txt', 'w') f

  • Python上下文管理器类和上下文管理器装饰器contextmanager用法实例分析

    本文实例讲述了Python上下文管理器类和上下文管理器装饰器contextmanager用法.分享给大家供大家参考,具体如下: 一. 什么是上下文管理器 上下文管理器是在Python2.5之后加入的功能,可以在方便的需要的时候比较精确地分配和释放资源, with便是上下文管理器的最广泛的应用, 比如: with open("test/test.txt","w") as f: f.write("hello") 这上会比使用try:...finall

  • python 上下文管理器及自定义原理解析

    这篇文章主要介绍了python 上下文管理器原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Python 提供了 with 语法用于简化资源操作的后续清除操作,是 try/finally 的替代方法,实现原理建立在上下文管理器之上. Python 提供了一个 contextmanager 装饰器,更进一步简化上下管理器的实现方式. 上下文管理器是Python2.5之后才出现的概念.上下文管理器规定了某个对象的使用范围,当进入或者离开了使

  • Python上下文管理器用法及实例解析

    这篇文章主要介绍了Python上下文管理器用法及实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 with上下文管理器 语法:with ... as ... 如:with open('test.txt', 'r') as fp,打开一个文件作为文件句柄对象赋值给fp with是一个语句块,上下文管理器中里面实现了两个方法:enter, exit,enter是进入代码块前自动调用的方法,exit是 退出with语句块时调用的,例如,文件对象

  • python上下文管理器异常问题解决方法

    对于异常的使用上,当我们在捕捉到错误时,会有一个抛出的选项让我们做决定.不过加入了上下文管理器后,就不用对异常进行选择了,因为其作用是不必抛出.下面我们就python上下文管理器处理异常进行说明,分析其中的三个参数,最后带来一个处理异常的实例供大家进行学习. 1.异常说明 异常可以在__exit__ 进行捕获并由你自己决定如何处理,是抛出还是不抛出.在__exit__ 里返回 True(没有return 就默认为 return False),就相当于告诉 Python解释器,这个异常我们已经捕获

  • python上下文管理器协议的实现

    目录 前言 todo:版本1 todo:版本2 前言 在上下文管理器协议的过程中,涉及到两个魔术方法__enter__方法 和 __exit__方法 在python中所有实现了上下文管理器协议的对象 都可以用使用with操作 with启动了对象的上下文管理器 上下文管理器协议: __enter__方法: 进入enter方法返回的结果被as后面的变量接收 exit: 退出with中所有的语句执行完毕执行 执行 exit 实现一个简单的文件操作来看下上下文管理器协议: class MyOpen:  

  • python上下文管理器使用场景及异常处理

    目录 引言 1.先看看最简单的例子,with语句 2.什么是上下文管理器? 3.上下文管理器的原理过程如下: 4.上下文管理器的应用场景: 4.1 数据库连接 4.2上下文管理器的异常处理 引言 使用上下文管理器,可以让代码更加优雅简洁.当然,上下文的管理器的作用不止于此,它内部的实现机制,能很好的处理代码异常,提升代码的复用性 1.先看看最简单的例子,with语句 # 创建一个文件写入字符串"Python" f = open('123.txt', 'w') f.write("

随机推荐