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编程中的包结构
Oct 25 Python
Python ftp上传文件
Feb 13 Python
python中闭包Closure函数作为返回值的方法示例
Dec 17 Python
在Python 2.7即将停止支持时,我们为你带来了一份python 3.x迁移指南
Jan 30 Python
Python使用matplotlib模块绘制图像并设置标题与坐标轴等信息示例
May 04 Python
python安装本地whl的实例步骤
Oct 12 Python
基于TensorFlow常量、序列以及随机值生成实例
Jan 04 Python
django从后台返回html代码的实例
Mar 11 Python
PyCharm设置注释字体颜色以及是否倾斜的操作
Sep 16 Python
python 实现一个图形界面的汇率计算器
Nov 09 Python
python基于win32api实现键盘输入
Dec 09 Python
Django实现在线无水印抖音视频下载(附源码及地址)
May 06 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
数字转英文
2006/12/06 PHP
改变Apache端口等配置修改方法
2008/06/05 PHP
PHP实现通过中文字符比率来判断垃圾评论的方法
2014/10/20 PHP
php遍历删除整个目录及文件的方法
2015/03/13 PHP
十大使用PHP框架的理由
2015/09/26 PHP
利用PHP访问带有密码的Redis方法示例
2017/02/09 PHP
JavaScript去除空格的几种方法
2006/10/03 Javascript
javascript eval函数深入认识
2009/02/21 Javascript
JavaScript 开发中规范性的一点感想
2009/06/23 Javascript
关于IE、Firefox、Opera页面呈现异同 写脚本很痛苦
2009/08/28 Javascript
js escape,unescape解决中文乱码问题的方法
2010/05/26 Javascript
在IE和VB中支持png图片透明效果的实现方法(vb源码打包)
2011/04/01 Javascript
jQuery动态添加删除select项(实现代码)
2013/09/03 Javascript
微信小程序 生命周期详解
2016/10/12 Javascript
JavaScript 详解预编译原理
2017/01/22 Javascript
浅谈js中的变量名和函数名重名
2017/02/13 Javascript
利用Chrome DevTools直接调试Node.js和JavaScript的方法详解(并行)
2017/02/16 Javascript
Vue中多个元素、组件的过渡及列表过渡的方法示例
2019/02/13 Javascript
简单了解JavaScript arguement原理及作用
2020/05/28 Javascript
Python实现Const详解
2015/01/27 Python
Python中SOAP项目的介绍及其在web开发中的应用
2015/04/14 Python
菜鸟使用python实现正则检测密码合法性
2016/01/05 Python
12步教你理解Python装饰器
2016/02/25 Python
详解PyTorch批训练及优化器比较
2018/04/28 Python
python的pygal模块绘制反正切函数图像方法
2019/07/16 Python
在Keras中利用np.random.shuffle()打乱数据集实例
2020/06/15 Python
bareMinerals官网:矿物质化妆品和护肤品
2018/02/04 全球购物
Ruby如何定义一个类
2012/10/08 面试题
2013年办公室秘书的个人自我鉴定
2013/10/24 职场文书
技术总监管理岗位职责
2014/03/09 职场文书
副职竞争上岗演讲稿
2014/05/12 职场文书
幼儿园安全责任书范本
2014/07/24 职场文书
授权委托书样本及填写说明
2014/09/19 职场文书
领导干部个人对照检查材料(群众路线)
2014/09/26 职场文书
党支部2014年度工作总结
2014/12/04 职场文书
正则表达式基础与常用验证表达式
2022/06/16 Javascript