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实现批量转换文件编码(批转换编码示例)
Jan 23 Python
Python获取网页上图片下载地址的方法
Mar 11 Python
python-itchat 获取微信群用户信息的实例
Feb 21 Python
检测python爬虫时是否代理ip伪装成功的方法
Jul 12 Python
python实现一行输入多个值和一行输出多个值的例子
Jul 16 Python
Python实现中值滤波去噪方式
Dec 18 Python
将labelme格式数据转化为标准的coco数据集格式方式
Feb 17 Python
django实现将修改好的新模型写入数据库
Mar 31 Python
基于python和flask实现http接口过程解析
Jun 15 Python
Pycharm同步远程服务器调试的方法步骤
Nov 04 Python
selenium自动化测试入门实战
Dec 21 Python
详解python字符串驻留技术
May 21 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
一个没有MYSQL数据库支持的简易留言本的编写
2006/10/09 PHP
PHP句法规则详解 入门学习
2011/11/09 PHP
数据库中排序的对比及使用条件详解
2012/02/23 PHP
使用PHP生成二维码的方法汇总
2015/07/22 PHP
CodeIgniter连贯操作的底层原理分析
2016/05/17 PHP
CI框架中类的自动加载问题分析
2016/11/21 PHP
PHP新特性详解之命名空间、性状与生成器
2017/07/18 PHP
Laravel 将数据表的数据导出,并生成seeds种子文件的方法
2019/10/09 PHP
基于jquery实现的鼠标拖拽元素复制并写入效果
2011/08/23 Javascript
js实现上传图片之上传前预览图片
2013/03/25 Javascript
使用ngView配合AngularJS应用实现动画效果的方法
2015/06/19 Javascript
jQuery AjaxUpload 上传图片代码
2016/02/02 Javascript
详解JavaScript正则表达式之分组匹配及反向引用
2016/03/09 Javascript
JavaScript中点击事件的写法
2016/06/28 Javascript
jQuery实现在新增加的元素上添加事件方法案例分析
2017/02/09 Javascript
D3.js进阶系列之CSV表格文件的读取详解
2017/06/06 Javascript
js事件委托和事件代理案例分享
2017/07/25 Javascript
JS库中的Particles.js在vue上的运用案例分析
2017/09/13 Javascript
JavaScript中立即执行函数实例详解
2017/11/04 Javascript
关于AOP在JS中的实现与应用详解
2019/05/06 Javascript
在SSM框架下用laypage和ajax实现分页和数据交互的方法
2019/09/27 Javascript
vue引入静态js文件的方法
2020/06/20 Javascript
python发送邮件功能实现代码
2016/07/15 Python
对Python中列表和数组的赋值,浅拷贝和深拷贝的实例讲解
2018/06/28 Python
python3+django2开发一个简单的人员管理系统过程详解
2019/07/23 Python
彻底搞懂 python 中文乱码问题(深入分析)
2020/02/28 Python
keras中epoch,batch,loss,val_loss用法说明
2020/07/02 Python
pycharm 实现复制一行的快捷键
2021/01/15 Python
基于Html5实现的react拖拽排序组件示例
2018/08/13 HTML / CSS
美国折衷生活方式品牌:Robert Graham
2018/07/13 全球购物
J2EE相关知识面试题
2013/08/26 面试题
光盘行动倡议书
2014/02/02 职场文书
小学端午节活动方案
2014/03/13 职场文书
工业自动化专业自荐信范文
2014/04/10 职场文书
党校学习党性分析材料
2014/12/19 职场文书
驾驶员安全责任协议书
2016/03/22 职场文书