Python上下文管理器Content Manager


Posted in Python onJune 26, 2021

在 Python 中,我们会经常听到上下文管理器(Context Manager),那我们探讨下这是什么,又有什么功能。

在 Python 中的上下文管理器中,使用 with 打开文件是使用最多的,其中离开 with 包含的语句后会执行一些类似于清理的工作,如关闭文件,关闭连接对象等操作。

实践

我们在代码实践的时候,忽略了在同一代码片段中,先打开文件,然后直接对文件进行其他处理,因为这样没有任何意义,资源是处于被占用的情况。

先看下面检测的代码:

#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
# MedusaSorcerer Script
import os


class OpenFile:
    def __init__(self):
        self.file = None

    def open(self, path):
        self.file = open(path, 'w')


if __name__ == '__main__':
    file_path = 'medusa.md'
    file = OpenFile()
    file.open(file_path)
    os.remove(file_path)

代码中我们把文件对象,进行了实例属性的方式引用,在此之后,我们使用 os 模块进行删除被写入的文件。执行改代码片段后,会出现以下内容:

Traceback (most recent call last):
  File "medusa/main.py", line 19, in <module>
    os.remove(file_path)
PermissionError: [WinError 32] 另一个程序正在使用此文件,进程无法访问。: 'medusa.md'

Process finished with exit code 1

那是因为被删除的文件没有得到资源释放。我们在上面的基础上进行套用函数的方式:

#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
# MedusaSorcerer Script
import os


class OpenFile:
    def __init__(self):
        self.file = None

    def open(self, path):
        self.file = open(path, 'w')


def open_file(path):
    file = OpenFile()
    file.open(path)


if __name__ == '__main__':
    file_path = 'medusa.md'
    open_file(file_path)
    os.remove(file_path)

这段代码会成功的被执行成功,原因是当你执行函数的时候,函数内的临时变量将被回收释放,因此 OpenFile 的实例对象被释放了,实例属性也就不存在而被释放,所以会执行成功。

那是否我们的操作都应该使用函数包裹的方式执行呢?with 的出现,完美解决了这个问题:

#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
# MedusaSorcerer Script
import os

if __name__ == '__main__':
    file_path = 'medusa.md'
    with open(file_path, 'w') as f:
        print(f)
    os.remove(file_path)

在 with 语法中,将后面打开文件的操作,返回的文件对象,赋值给 f 变量,在结构体中输出了 f 变量的内容,并且在结构体外删除了该文件:

medusa\python.exe medusa/main.py
<_io.TextIOWrapper name='medusa.md' mode='w' encoding='cp936'>

Process finished with exit code 0

在没有使用 close() 的情况下,依旧可以对文件进行删除,这就是上下文管理的美妙。

实现

上下文管理,实际上是实现了 __enter__ 和 __exit__ 方法:

#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
# MedusaSorcerer Script


class Medusa:

    def __init__(self):
        print('__init__')

    def __enter__(self):
        print('__enter__')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('__exit__')


if __name__ == '__main__':
    medusa = Medusa()
    with medusa:
        print('with object')
    print('finish')

以下是输出结果:

__init__
__enter__
with object
__exit__
finish

我们发现魔法方法在结合某些语法后会发生自动调度,所以,上下文管理中就在自动调度中,关闭了某些对象。

优点

实现上下文管理可以简化我们的代码,让代码更加简单易读,使用最少的代码量,就可以完成全部工作。

到此这篇关于Python上下文管理器Content Manager的文章就介绍到这了,更多相关Python上下文管理器内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
urllib2自定义opener详解
Feb 07 Python
Python实现读取目录所有文件的文件名并保存到txt文件代码
Nov 22 Python
利用Python和OpenCV库将URL转换为OpenCV格式的方法
Mar 27 Python
python绘制多个子图的实例
Jul 07 Python
Python交互式图形编程的实现
Jul 25 Python
使用python批量修改文件名的方法(视频合并时)
Mar 24 Python
Django 在iframe里跳转顶层url的例子
Aug 21 Python
Python 内置函数globals()和locals()对比详解
Dec 23 Python
Python实现计算长方形面积(带参数函数demo)
Jan 18 Python
Python实现动态给类和对象添加属性和方法操作示例
Feb 29 Python
python读取excel数据绘制简单曲线图的完整步骤记录
Oct 30 Python
Django如何重置migration的几种情景
Feb 24 Python
仅用几行Python代码就能复制她的U盘文件?
总结几个非常实用的Python库
Jun 26 #Python
手残删除python之后的补救方法
Python办公自动化之教你用Python批量识别发票并录入到Excel表格中
Python Pandas模块实现数据的统计分析的方法
Jun 24 #Python
FP-growth算法发现频繁项集——发现频繁项集
能让Python提速超40倍的神器Cython详解
Jun 24 #Python
You might like
历史证明,懒惰才是推动科学发展技术进步的动力
2021/03/02 无线电
实现“上一页”和“下一页按钮
2006/10/09 PHP
php实现快速排序法函数代码
2012/08/27 PHP
thinkphp模板的包含与渲染实例分析
2014/11/26 PHP
PHP让数组中有相同值的组成新的数组实例
2017/12/31 PHP
javascript 对表格的行和列都能加亮显示
2008/12/26 Javascript
基于jquery的动态创建表格的插件
2011/04/05 Javascript
jquery插件制作 手风琴Panel效果实现
2012/08/17 Javascript
jQuery实现带滑动条的菜单效果代码
2015/08/26 Javascript
JS实现队列与堆栈的方法
2016/04/21 Javascript
vue.js指令v-model实现方法
2016/12/05 Javascript
JS重载实现方法分析
2016/12/16 Javascript
关于vue单文件中引用路径的处理方法
2018/01/08 Javascript
vue项目实现记住密码到cookie功能示例(附源码)
2018/01/31 Javascript
vue中的 $slot 获取插槽的节点实例
2019/11/12 Javascript
react 生命周期实例分析
2020/05/18 Javascript
vue使用axios实现excel文件下载的功能
2020/07/16 Javascript
python文件和目录操作函数小结
2014/07/11 Python
为Python的Tornado框架配置使用Jinja2模板引擎的方法
2016/06/30 Python
利用python 更新ssh 远程代码 操作远程服务器的实现代码
2018/02/08 Python
Python框架Flask的基本数据库操作方法分析
2018/07/13 Python
Python爬虫框架Scrapy常用命令总结
2018/07/26 Python
Python开发网站目录扫描器的实现
2019/02/21 Python
django基础学习之send_mail功能
2019/08/07 Python
python pygame实现滚动横版射击游戏城市之战
2019/11/25 Python
python操作cfg配置文件方式
2019/12/22 Python
TensorFlow中如何确定张量的形状实例
2020/06/23 Python
Html5导航栏吸顶方案原理与对比实现
2020/06/10 HTML / CSS
英国Iceland杂货店:网上食品购物
2020/12/16 全球购物
北大自主招生自荐信
2013/10/19 职场文书
2015年银行大堂经理工作总结
2015/04/24 职场文书
pandas求平均数和中位数的方法实例
2021/08/04 Python
使用canvas对video视频某一刻截图功能
2021/09/25 HTML / CSS
一篇文章弄清楚Ajax请求的五个步骤
2022/03/17 Javascript
php解析非标准json、非规范json的方式实例
2022/05/10 PHP
MySQL提升大量数据查询效率的优化神器
2022/07/07 MySQL