• python中的上下文管理器


    python中,我们会经常使用下面的代码:

    with open("1.txt", 'r') as f:
    	f.read()
    	...
    
    • 1
    • 2
    • 3

    这段代码是用来读某个文件,with在这里可以确保不管使用过程中是否发生异常,都会执行必要的文件关闭操作,释放资源。with语句,简化了代码,有效的避免资源泄漏的发生。

    上述代码也可以利用try finally语句完成:

    try:
        f = open('1.txt', 'r')
    finally:
        if f:
            f.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    明显看出来这段代码相对更加复杂,python因追求简洁的pythonic编码风格,所以便定义了with写法。

    with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放。

    上下文管理器

    要想理解with,首先要了解上下文管理器,上下文管理器,它是python中的一种协议,实现了这种协议的类的实例,都是上下文管理器对象。

    文件的输入输出、数据库的连接断开等,都是很常见的资源管理操作。但资源都是有限的,在写程序时,我们必须保证这些资源在使用过后得到释放,不然就容易造成资源泄露,轻者使得系统处理缓慢,重则会使系统崩溃。上下文管理器,能够帮助你自动分配并且释放资源。

    剖析一下上面的with语句:

    1. 上下文表达式:with open('test.txt') as f:
    2. 上下文管理器:open('test.txt')
    3. f是上下文管理器返回的资源对象
    4. with关键字表示使用上下文管理器
    
    • 1
    • 2
    • 3
    • 4

    在python中实现上下文协议并创建上下文管理器对象的方法有两种,一种是基于类的上下文管理器,一种是基于生成器的上下文管理器。

    基于类的上下文管理器

    用类实现上下文管理器,在类定义的时候,实现两个方法”enter()”和方法“exit()”两个方法即可。其中,方法“enter()”返回需要被管理的资源;方法“exit()”里通常会存在一些释放、清理资源的操作,比如这个例子中的关闭文件等等。

    类实现的上下文管理器的例子:
    在这里插入图片描述
    代码执行的过程:

    1. 方法__init__()被调用,程序初始化对象FileManager,使得文件名(name)是“test.txt”,文件模式(mode)是‘w’
    2. 方法enter()被调用,文件test.txt以写入的模式被打开,并且返回资源对象赋给变量f
    3. 字符串“hello world”被写入文件test.txt
    4. 方法exit()被调用,负责关闭之前打开的文件流

    方法“exit()”中的参数“exc_type, exc_val,exc_tb”,分别表示 exception_type、exception_value 和 traceback。当我们执行含有上下文管理器的 with 语句时,如果有异常抛出,异常的信息就会包含在这三个变量中,传入方法“exit()”。

    基于生成器的上下文管理器

    可以使用装饰器 contextlib.contextmanager,来定义自己所需的基于生成器的上下文管理器,用以支持 with 语句。
    在这里插入图片描述
    这段代码中,函数 file_manager() 是一个生成器,当我们执行 with 语句时,便会打开文件,并返回文件对象 f;当 with 语句执行完后,finally中的关闭文件操作便会执行。

    两种类型的上下文管理器的比较:
    基于类的上下文管理器和基于生成器的上下文管理,这两者在功能上是一致的,但:

    • 基于类的上下文管理器更加灵活,适用于大型的系统开发
    • 基于生成器的上下文管理器更加方便、简洁,适用于中小型程序

    其他讲解python上下文管理器的文章:
    https://www.jianshu.com/p/20fd3335648a
    https://www.liaoxuefeng.com/wiki/1016959663602400/1017607179232640
    https://blog.csdn.net/Kwoky/article/details/106682609
    https://blog.csdn.net/Kwoky/article/details/106682609
    https://www.runoob.com/python3/python-with.html
    https://www.cnblogs.com/wongbingming/p/10519553.html
    https://juejin.cn/post/6993180184178327582

  • 相关阅读:
    如何在 ASP.NET Core 中使用 Quartz.NET
    计算机毕业设计Java江西婺源旅游文化推广系统(源码+系统+mysql数据库+lw文档)
    保姆教程系列三、Nacos Config--服务配置
    【单元测试】--高级主题
    Verilog数字系统教程学习——Verilog语法的基本概念
    1678、设计Goal解析器(暴力+栈+replace)
    点云从入门到精通技术详解100篇-基于 LSTM 的点云降采样(下)
    Spring——如何理解Spring,DI和IoC
    恶意文件分类
    word插入公式/endnote
  • 原文地址:https://blog.csdn.net/qq_38048756/article/details/125624430