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的身份证号码自动生成程序
Aug 15 Python
python回溯法实现数组全排列输出实例分析
Mar 17 Python
python字典DICT类型合并详解
Aug 17 Python
Python编程中NotImplementedError的使用方法
Apr 21 Python
python连接mongodb密码认证实例
Oct 16 Python
使用Python抓取豆瓣影评数据的方法
Oct 17 Python
对python中if语句的真假判断实例详解
Feb 18 Python
python如何以表格形式打印输出的方法示例
Jun 21 Python
简单了解Python matplotlib线的属性
Jun 29 Python
Python3 webservice接口测试代码详解
Jun 23 Python
python 基于selectors库实现文件上传与下载
Dec 31 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
如何冲泡挂耳包咖啡?技巧是什么
2021/03/04 冲泡冲煮
php线性表顺序存储实现代码(增删查改)
2012/02/16 PHP
php5.3以后的版本连接sqlserver2000的方法
2014/07/28 PHP
页面利用渐进式JPEG来提升用户体验度
2014/12/01 PHP
Joomla调用系统自带编辑器的实现方法
2016/05/05 PHP
php 查找数组元素提高效率的方法详解
2017/05/05 PHP
深入理解Yii2.0乐观锁与悲观锁的原理与使用
2017/07/26 PHP
artDialog 4.1.5 Dreamweaver代码提示/补全插件 附下载
2012/07/31 Javascript
Javascript的时间戳和php的时间戳转换注意事项
2013/04/12 Javascript
JQuery设置和去除disabled属性的5种方法总结
2013/05/16 Javascript
在javascript中实现函数数组的方法
2013/12/25 Javascript
parentElement,srcElement的使用小结
2014/01/13 Javascript
javascript中的事件代理初探
2014/03/08 Javascript
js 获取时间间隔实现代码
2014/05/12 Javascript
提高NodeJS中SSL服务的性能
2014/07/15 NodeJs
JavaScript设计模式之建造者模式介绍
2014/12/28 Javascript
如何改进javascript代码的性能
2015/04/02 Javascript
jquery封装插件时匿名函数形参和实参的写法解释
2017/02/14 Javascript
JavaScript链式调用实例浅析
2018/12/19 Javascript
原生JS实现逼真的图片3D旋转效果详解
2019/02/16 Javascript
JS判断数组是否包含某元素实现方法汇总
2020/06/24 Javascript
JavaScript实现简易计算器小功能
2020/10/22 Javascript
jquery实现点击左右按钮切换图片
2021/01/27 jQuery
Python虚拟环境Virtualenv使用教程
2015/05/18 Python
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
2019/01/05 Python
浅谈在JupyterNotebook下导入自己的模块的问题
2020/04/16 Python
浅谈keras中的keras.utils.to_categorical用法
2020/07/02 Python
html5实现移动端适配完美写法
2017/11/16 HTML / CSS
GUESS盖尔斯法国官网:美国时尚品牌
2016/09/23 全球购物
英国老牌潮鞋店:Offspring
2019/08/19 全球购物
公司综合部的成员自我评价分享
2013/11/05 职场文书
抵押贷款承诺书
2014/05/30 职场文书
全国优秀教师事迹材料
2014/08/26 职场文书
MySQL中的隐藏列的具体查看
2021/09/04 MySQL
船舶调度指挥系统——助力智慧海事
2022/02/18 无线电
JS前端canvas交互实现拖拽旋转及缩放示例
2022/08/05 Javascript