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数组条件过滤filter函数使用示例
Jul 22 Python
python实现简单ftp客户端的方法
Jun 28 Python
深入理解NumPy简明教程---数组2
Dec 17 Python
Python变量和数据类型详解
Feb 15 Python
python自动查询12306余票并发送邮箱提醒脚本
May 21 Python
利用Django提供的ModelForm增删改数据的方法
Jan 06 Python
pytorch中如何使用DataLoader对数据集进行批处理的方法
Aug 06 Python
如何将你的应用迁移到Python3的三个步骤
Dec 22 Python
Python xlrd excel文件操作代码实例
Mar 10 Python
Python+unittest+requests 接口自动化测试框架搭建教程
Oct 09 Python
python3中for循环踩过的坑记录
Dec 14 Python
Python Matplotlib绘制两个Y轴图像
Apr 13 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
便携利器 — TECSUN PL-365简评
2021/03/02 无线电
PHP运行出现Notice : Use of undefined constant 的完美解决方案分享
2012/03/05 PHP
PHP程序员基本要求和必备技能
2014/05/09 PHP
ThinkPHP实现一键清除缓存方法
2014/06/26 PHP
php邮件发送的两种方式
2020/04/28 PHP
php获取远程文件内容的函数
2015/11/02 PHP
基于jQuery的弹出警告对话框美化插件(警告,确认和提示)
2010/06/10 Javascript
jquery插件制作 表单验证实现代码
2012/08/17 Javascript
JavaScript实现动态创建CSS样式规则方案
2014/09/06 Javascript
JavaScript代码性能优化总结篇
2016/05/15 Javascript
js通过classname来获取元素的方法
2016/11/24 Javascript
vue router学习之动态路由和嵌套路由详解
2017/09/21 Javascript
通过js控制时间,一秒一秒自己动的实例
2017/10/25 Javascript
微信小程序基于slider组件动态修改标签透明度的方法示例
2017/12/04 Javascript
基于vue-ssr的静态网站生成器VuePress 初体验
2018/04/17 Javascript
vue移动端下拉刷新和上拉加载的实现代码
2018/09/08 Javascript
Vue组件内部实现一个双向数据绑定的实例代码
2019/04/04 Javascript
python用字典统计单词或汉字词个数示例
2014/04/22 Python
Python按行读取文件的简单实现方法
2016/06/22 Python
实例讲解Python中SocketServer模块处理网络请求的用法
2016/06/28 Python
对于Python中RawString的理解介绍
2016/07/07 Python
python九九乘法表的实例
2017/09/26 Python
python实现创建新列表和新字典,并使元素及键值对全部变成小写
2019/01/15 Python
python 实现敏感词过滤的方法
2019/01/21 Python
基于Python实现签到脚本过程解析
2019/10/25 Python
Python 获取命令行参数内容及参数个数的实例
2019/12/20 Python
python数据库编程 Mysql实现通讯录
2020/03/27 Python
python如何实现读取并显示图片(不需要图形界面)
2020/07/08 Python
Python如何把字典写入到CSV文件的方法示例
2020/08/23 Python
python识别验证码的思路及解决方案
2020/09/13 Python
python基于selenium爬取斗鱼弹幕
2021/02/20 Python
python 基于pygame实现俄罗斯方块
2021/03/02 Python
Java工程师面试集锦之Spring框架
2013/06/16 面试题
五一劳动节活动记录
2014/03/23 职场文书
生产操作工岗位职责
2014/09/16 职场文书
2015年事业单位工作总结
2015/04/27 职场文书