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 相关文章推荐
Python Mysql自动备份脚本
Jul 14 Python
Python模拟登录验证码(代码简单)
Feb 06 Python
python中计算一个列表中连续相同的元素个数方法
Jun 29 Python
在Python中居然可以定义两个同名通参数的函数
Jan 31 Python
Python Selenium 之关闭窗口close与quit的方法
Feb 13 Python
Python OpenCV 使用滑动条来调整函数参数的方法
Jul 08 Python
flask框架自定义过滤器示例【markdown文件读取和展示功能】
Nov 08 Python
详解从Django Allauth中进行登录改造小结
Dec 18 Python
python接口自动化如何封装获取常量的类
Dec 24 Python
keras实现图像预处理并生成一个generator的案例
Jun 17 Python
python 检测图片是否有马赛克
Dec 01 Python
Python利用folium实现地图可视化
May 23 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
用PHP生成静态HTML速度快类库
2007/03/18 PHP
php获取mysql字段名称和其它信息的例子
2014/04/14 PHP
让CodeIgniter数据库缓存自动过期的处理的方法
2014/06/12 PHP
php返回json数据函数实例
2014/10/09 PHP
PHP从FLV文件获取视频预览图的方法
2015/03/12 PHP
CI框架源码解读之利用Hook.php文件完成功能扩展的方法
2016/05/18 PHP
PHP 类与构造函数解析
2017/02/06 PHP
php反射学习之不用new方法实例化类操作示例
2019/06/14 PHP
网页常用特效代码整理
2006/06/23 Javascript
JavaScript的类型简单说明
2010/09/03 Javascript
JavaScript实现从数组中选出和等于固定值的n个数
2014/09/03 Javascript
使用C++为node.js写扩展模块
2015/04/22 Javascript
新手快速学习JavaScript免费教程资源汇总
2015/06/25 Javascript
js验证身份证号有效性并提示对应信息
2015/10/19 Javascript
全面理解JavaScript中的闭包
2016/05/12 Javascript
js实现图片旋转 js滚动鼠标中间对图片放大缩小
2017/07/05 Javascript
开发Vue树形组件的示例代码
2017/12/21 Javascript
基于jquery.page.js实现分页效果
2018/01/01 jQuery
vue-cli开发环境实现跨域请求的方法
2018/04/07 Javascript
利用Node.js如何实现文件循环覆写
2019/04/05 Javascript
[01:50]WODOTA制作 DOTA2中文宣传片《HERO》
2013/04/28 DOTA
python中正则表达式的使用详解
2014/10/17 Python
Python中getattr函数和hasattr函数作用详解
2016/06/14 Python
对json字符串与python字符串的不同之处详解
2018/12/19 Python
浅谈Python中的全局锁(GIL)问题
2019/01/11 Python
Numpy对数组的操作:创建、变形(升降维等)、计算、取值、复制、分割、合并
2019/08/28 Python
python命令 -u参数用法解析
2019/10/24 Python
Django+boostrap 美化admin后台的操作
2020/03/11 Python
Python 中由 yield 实现异步操作
2020/05/04 Python
总结Pyinstaller的坑及终极解决方法(小结)
2020/09/21 Python
Levi’s美国官网:美国著名的牛仔裤品牌
2016/08/19 全球购物
固特异美国在线轮胎店:Goodyear Tire
2019/02/23 全球购物
汉语专业应届生求职信
2013/10/01 职场文书
个人四风问题对照检查材料思想汇报
2014/10/06 职场文书
教你怎么用python实现字符串转日期
2021/05/24 Python
详细了解java监听器和过滤器
2021/07/09 Java/Android