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之list和str比较
Sep 20 Python
使用Python绘制图表大全总结
Feb 11 Python
python实现逻辑回归的方法示例
May 02 Python
python代码实现ID3决策树算法
Dec 20 Python
实用自动化运维Python脚本分享
Jun 04 Python
python爬虫实例详解
Jun 19 Python
Python实现的远程文件自动打包并下载功能示例
Jul 12 Python
Python3.7 读取 mp3 音频文件生成波形图效果
Nov 05 Python
Python局部变量与全局变量区别原理解析
Jul 14 Python
python数据分析之用sklearn预测糖尿病
Apr 22 Python
python flask开发的简单基金查询工具
Jun 02 Python
浅谈Python数学建模之固定费用问题
Jun 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微信公众平台开发类实例
2015/04/01 PHP
php die()与exit()的区别实例详解
2016/12/03 PHP
php处理抢购类功能的高并发请求
2018/02/08 PHP
YII2框架中添加自定义模块的方法实例分析
2020/03/18 PHP
js限制文本框为整数和货币的函数代码
2010/10/13 Javascript
表头固定(利用jquery实现原理介绍)
2012/11/08 Javascript
js获取html参数及向swf传递参数应用介绍
2013/02/18 Javascript
Jquery实现控件的隐藏和显示实例
2014/02/08 Javascript
Jquery动态替换div内容及动态展示的方法
2015/01/23 Javascript
简介JavaScript中的italics()方法的使用
2015/06/08 Javascript
jQuery进行组件开发完整实例
2015/12/15 Javascript
jQuery实现微信长按识别二维码功能
2016/08/26 Javascript
实例讲解JavaScript中call、apply、bind方法的异同
2016/09/13 Javascript
js手机号4位显示空格,银行卡每4位显示空格效果
2017/03/23 Javascript
Bootstrap进度条与AJAX后端数据传递结合使用实例详解
2017/04/23 Javascript
Vuex 入门教程
2018/01/10 Javascript
微信小程序实现签到弹窗动画
2020/09/21 Javascript
python 文件和路径操作函数小结
2009/11/23 Python
Python3 正在毁灭 Python的原因分析
2014/11/28 Python
使用Pyrex来扩展和加速Python程序的教程
2015/04/13 Python
Python将多个excel表格合并为一个表格
2021/02/22 Python
对python遍历文件夹中的所有jpg文件的实例详解
2018/12/08 Python
python字符串分割及字符串的一些常规方法
2019/07/24 Python
python实现根据文件格式分类
2019/10/31 Python
浅析Django中关于session的使用
2019/12/30 Python
Python基于Socket实现简单聊天室
2020/02/17 Python
python GUI库图形界面开发之PyQt5切换按钮控件QPushButton详细使用方法与实例
2020/02/28 Python
解决django FileFIELD的编码问题
2020/03/30 Python
Pytorch 使用opnecv读入图像由HWC转为BCHW格式方式
2020/06/02 Python
Keras load_model 导入错误的解决方式
2020/06/09 Python
keras分类之二分类实例(Cat and dog)
2020/07/09 Python
详解使用scrapy进行模拟登陆三种方式
2021/02/21 Python
乔丹诺(Giordano)酒庄德国官网:找到最好的意大利葡萄酒
2017/12/28 全球购物
厨房工作人员岗位职责
2013/11/15 职场文书
小学校园之星事迹材料
2014/05/16 职场文书