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实现带声音的摩斯码翻译实现方法
May 20 Python
将TensorFlow的模型网络导出为单个文件的方法
Apr 23 Python
详解python运行三种方式
May 13 Python
解决Django一个表单对应多个按钮的问题
Jul 18 Python
python加载自定义词典实例
Dec 06 Python
Python反爬虫伪装浏览器进行爬虫
Feb 28 Python
Python通过kerberos安全认证操作kafka方式
Jun 06 Python
详解pytorch tensor和ndarray转换相关总结
Sep 03 Python
Python Merge函数原理及用法解析
Sep 16 Python
利用Python实现自动扫雷小脚本
Dec 17 Python
解决Pytorch中关于model.eval的问题
May 22 Python
 Python 中 logging 模块使用详情
Mar 03 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初学者最感迷茫的问题小结
2010/03/27 PHP
php获取操作系统语言代码
2013/11/04 PHP
PHP preg_match实现正则表达式匹配功能【输出是否匹配及匹配值】
2017/07/19 PHP
laravel Model 执行事务的实现
2019/10/10 PHP
jQuery Ajax方法调用 Asp.Net WebService 的详细实例代码
2011/04/27 Javascript
原生js的弹出层且其内的窗口居中
2014/05/14 Javascript
原生的html元素选择器类似jquery选择器
2014/10/15 Javascript
JavaScript实现防止网页被嵌入Frame框架的代码分享
2014/12/29 Javascript
JS手机端touch事件计算滑动距离的方法示例
2017/10/26 Javascript
为输入框加入数字js校验代码分享
2017/11/02 Javascript
JS实现图片转换成base64的各种应用场景实例分析
2018/06/22 Javascript
详解如何在微信小程序中愉快地使用sass
2018/07/30 Javascript
Vue实现底部侧边工具栏的实例代码
2018/09/03 Javascript
layui 根据后台数据动态创建下拉框并同时默认选中的实例
2019/09/02 Javascript
Vue实现简单的拖拽效果
2020/08/25 Javascript
Vue+Element ui 根据后台返回数据设置动态表头操作
2020/09/21 Javascript
详解Vue的异步更新实现原理
2020/12/22 Vue.js
python操作MySQL数据库的方法分享
2012/05/29 Python
Python 变量类型及命名规则介绍
2013/06/08 Python
Python中关键字is与==的区别简述
2014/07/31 Python
Python随机生成彩票号码的方法
2015/03/05 Python
Linux下使用python调用top命令获得CPU利用率
2015/03/10 Python
Python实现把xml或xsl转换为html格式
2015/04/08 Python
详解Python中的array数组模块相关使用
2016/07/05 Python
让python 3支持mysqldb的解决方法
2017/02/14 Python
python爬虫泛滥的解决方法详解
2020/11/25 Python
基于Python中Remove函数的用法讨论
2020/12/11 Python
真正了解CSS3背景下的@font face规则
2017/05/04 HTML / CSS
怎样有效的进行自我评价
2013/10/06 职场文书
开门红主持词
2014/04/02 职场文书
应聘销售主管的求职信
2014/04/26 职场文书
环保建议书600字
2014/05/14 职场文书
村党的群众路线教育实践活动工作总结
2014/10/25 职场文书
雾霾停课通知
2015/04/24 职场文书
民事上诉状范文
2015/05/22 职场文书
《打电话》教学反思
2016/02/22 职场文书