首页 > 编程语言 >[3]Python高级特性-【4】上下文管理器

[3]Python高级特性-【4】上下文管理器

时间:2023-04-15 10:34:10浏览次数:36  
标签:__ 语句 管理器 Python self 上下文 资源

Python中的上下文管理器(Context Manager)是一种用于管理资源的技术,例如文件、网络连接、数据库连接等。上下文管理器使用with语句来自动获取和释放资源,确保资源的正确管理和关闭,避免资源泄漏和错误。

在本教程中,我们将学习如何创建和使用上下文管理器,了解上下文管理器的原理和用途,并通过实际的示例来展示其在Python编程中的实际应用。

什么是上下文管理器?

上下文管理器是实现了__enter__()和__exit__()两个特殊方法的对象,它们用于定义在with语句中资源的获取和释放行为。__enter__()方法在with语句块执行前调用,负责获取资源并返回资源对象;__exit__()方法在with语句块执行完毕后调用,负责释放资源。上下文管理器可以用于确保资源的正确打开和关闭,以及在出现异常时执行清理操作。

上下文管理器可以使用with语句来管理资源,例如:

with open('file.txt', 'r') as file:
    # 在这里使用file对象进行文件操作
# 在这里文件已经自动关闭

在上面的例子中,open()函数返回的file对象是一个上下文管理器,它负责在with语句块中自动打开和关闭文件。

创建上下文管理器

我们可以通过两种方式来创建上下文管理器:通过类和通过函数装饰器。

通过类创建上下文管理器

要通过类创建上下文管理器,我们需要定义一个类,并在类中实现__enter__()和__exit__()方法。__enter__()方法负责获取资源,并返回资源对象;__exit__()方法负责释放资源。例如:

class MyContext:
    def __enter__(self):
        print('Entering the context')
        # 获取资源,例如打开文件、建立数据库连接等
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('Exiting the context')
        # 释放资源,例如关闭文件、关闭数据库连接等
        if exc_type is not None:
            print(f'An exception of type {exc_type} occurred with value {exc_val}')
        return False  # 返回False表示不处理异常,异常会继续传播

# 使用自定义的上下文管理器
with MyContext() as my_context:
    print('Inside the context')
    # 在这里使用资源对象进行操作

print('Outside the context')

在上面的例子中,MyContext类是一个自定义的上下文管理器,通过with语句进行资源的获取和释放。__enter__()方法返回self作为资源对象,__exit__()方法在with语句块执行完毕后自动被调用,负责释放资源。

通过函数装饰器创建上下文管理器

除了使用类来创建上下文管理器外,我们还可以使用函数装饰器来创建上下文管理器。函数装饰器是一种将一个函数包装成另一个函数的技术,在这种情况下,我们可以使用contextlib模块中的contextmanager装饰器来创建上下文管理器。例如:

from contextlib import contextmanager

@contextmanager
def my_context():
    try:
        print('Entering the context')
        # 获取资源,例如打开文件、建立数据库连接等
        yield  # yield语句之前的代码相当于__enter__()方法
    except Exception as e:
        print(f'An exception of type {type(e)} occurred with value {e}')
    finally:
        print('Exiting the context')
        # 释放资源,例如关闭文件、关闭数据库连接等
        # yield语句之后的代码相当于__exit__()方法

# 使用函数装饰器创建上下文管理器
with my_context():
    print('Inside the context')
    # 在这里使用资源进行操作

print('Outside the context')

在上面的例子中,my_context()函数被contextmanager装饰器修饰,使其成为一个上下文管理器。yield语句之前的代码相当于__enter__()方法,yield语句之后的代码相当于__exit__()方法。yield语句用于指示资源的获取和释放时机,并允许在with语句块中使用资源。

使用上下文管理器

一旦创建了上下文管理器,我们就可以使用with语句来管理资源的获取和释放。with语句的语法如下:

with 上下文管理器 as 资源对象:
    # 在这里使用资源对象进行操作

当with语句执行时,__enter__()方法会被调用用于获取资源,并将资源对象赋值给资源对象。在with语句块中,我们可以使用资源对象来进行操作。一旦with语句块执行完毕,无论是否发生了异常,__exit__()方法都会被调用用于释放资源。

下面是一个完整的示例,演示了如何使用上下文管理器来处理文件的读写操作:

class FileHandler:
    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 FileHandler('file.txt', 'r') as file:
    content = file.read()
    print(content)

# 文件已自动关闭

在上面的例子中,FileHandler类是一个自定义的上下文管理器,负责处理文件的读写操作。__enter__()方法中通过open()函数打开了文件,并返回了文件对象。在with语句块中,我们可以使用file对象来进行文件的读取操作。一旦with语句块执行完毕,无论是否发生了异常,__exit__()方法都会被调用用于关闭文件。

上下文管理器在处理资源时具有很多优点,例如在异常发生时能够自动释放资源,确保资源的正确获取和释放。此外,使用上下文管理器还能够使代码更加简洁和可读,使得资源的管理更加优雅。

总结

上下文管理器是一种用于管理资源的技术,它通过实现__enter__()和__exit__()方法来自动处理资源的获取和释放。在Python中,上下文管理器可以通过类来创建,也可以使用函数装饰器来创建。通过with语句,我们可以在代码中优雅地处理资源的管理,确保资源的正确获取和释放,同时使代码更加简洁和可读。

希望本教程能够帮助你理解和使用Python中的上下文管理器。使用上下文管理器能够帮助你更好地管理资源,提高代码的可维护性和可靠性。

标签:__,语句,管理器,Python,self,上下文,资源
From: https://blog.51cto.com/jzj2023/6192236

相关文章

  • python3多线程-线程池和优先队列
    1、介绍有两种线程池方案。各线程持续存在,从任务池获取任务进行执行按照需求创建线程,每个线程只执行一个任务,结束完毕则该线程结束2、准备(1)任务池task_list任务池是用于准备各任务单元的环境,比如http爆破时的请求参数,读写文件时的路径。任务池的准备可能会占用一定时间,边准......
  • 《Python算法交易实战》——yfinace获取yahoo财经数据
    因为从2021年11月1日起,用户无法从中国大陆地区使用Yahoo产品与服务所以下面两个错误,都是代理配置的问题error:Notimezonefound,symbolmaybedelistederror:Nodatafoundforthisdaterange,symbolmaybedelisted以下是解决办法:1.实现强劲上网,保证你可以在浏览器......
  • Python运行过程中想要保存数据
    前言自己写的Python代码循环太多了,想缩减一下迭代步数,但又舍不得之前已经产生的数据。就想去看看这个问题有无解决方案。理论上来说,中途中止看到现在程序运行的情况应该是合理的。所以,就找到了这个知乎问题:参考链接:能不能在手动停止python程序的时候将处理到一半的数据保存出......
  • python3多线程-线程同步
    1、介绍多线程同时访问和操作同一资源,可能会造成异常。解决办法是对资源进行限制,同一时间只允许一个线程进行访问和操作。这里的资源,一般是指方法、函数或者代码块。即由多行代码组成,在逻辑上属于不可切分的操作。2、线程同步使用Thread对象的Lock和Rlock可以实现简单......
  • python3模块和相关
    1、模块为了方便管理类和函数,将其保存到不同的文件中,文件又可以存放在不同的目录下。这里的文件和目录,即python模块。(1)通过关键字import进行导入(2)一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。(3)搜索路径被存储在sys模块......
  • Python字符串处理
    Python之正则表达式正则表达式重在处理字符串规则普通字符importre#普通字符result=re.findall("p","python")print(result,type(result))result=re.findall("o","Ilovepython")print(result,type(result))预定义字符模式描述\d匹配所有数字0......
  • Python入门基础实例讲解——两个数字比大小,并输出最大值
    嗨害大家好鸭!我是小熊猫~今天也是给大家带来干货的一天~pycharm永久激活码可以从这里找到我:输出:print()print()方法用于打印输出,最常见的一个函数。比较运算符>:大于,如果运算符前面的值大于后面的值,则返回True;否则返回False<:小于,如果运算符前面的值小于后面的值,则返回True;否......
  • 使用清华镜像安装python第三方库
    1,在cmd安装python第三方库提示超时,可以使用清华镜像安装  pip3install-ihttps://pypi.tuna.tsinghua.edu.cn/simple--upgrade库名 ......
  • 【Windows / Linux】python 换 豆瓣源
    python换豆瓣源-直接运行Python代码即可 Windows版importospath=os.getenv('APPDATA')#获取环境变量data="""[global]timeout=6000index-url=http://pypi.douban.com/simple/trusted-host=pypi.douban.com"""#写入的数据fo......
  • python_一切皆是对象
    minicondapython中的对象的三个基本特征查看idtype()查看类型,print()查看值python和java面相对象的区别函数和类的对象特性装饰器用到了那个特性python中函数也可以当做返回值函数赋值给另外一个变量类赋值给另外一个变量将函数,类添加到一个列表中可以将......