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算法学习之计数排序实例
Dec 18 Python
简单讲解Python中的数字类型及基本的数学计算
Mar 11 Python
Python分治法定义与应用实例详解
Jul 28 Python
python对离散变量的one-hot编码方法
Jul 11 Python
Python类和对象的定义与实际应用案例分析
Dec 27 Python
Python openpyxl读取单元格字体颜色过程解析
Sep 03 Python
python数据预处理方式 :数据降维
Feb 24 Python
Keras自定义实现带masking的meanpooling层方式
Jun 16 Python
keras训练浅层卷积网络并保存和加载模型实例
Jul 02 Python
Python‘==‘ 及 ‘is‘相关原理解析
Sep 05 Python
如何通过python计算圆周率PI
Nov 11 Python
python爬取股票最新数据并用excel绘制树状图的示例
Mar 01 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
2019十大人气国漫
2020/03/13 国漫
PHP 解决session死锁的方法
2013/06/20 PHP
PHP实现的多文件上传类及用法示例
2016/05/06 PHP
简单解析PHP程序的运行流程
2016/06/23 PHP
Linux下源码包安装Swoole及基本使用操作图文详解
2019/04/02 PHP
YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例
2020/03/18 PHP
jQuery中与toggleClass等价的程序段 以及未来学习的方向
2010/03/18 Javascript
Javascript(AJAX)解析XML的代码(兼容FIREFOX/IE)
2010/07/11 Javascript
JQuery自定义事件的应用 JQuery最佳实践
2010/08/01 Javascript
JavaScript中的变量声明早于赋值分析
2012/03/01 Javascript
使用js判断控件是否获得焦点
2014/01/03 Javascript
JavaScript中的acos()方法使用详解
2015/06/14 Javascript
jQuery原生的动画效果
2015/07/10 Javascript
javascript加载xml 并解析各节点的值(实现方法)
2016/10/12 Javascript
浅谈Node.js:fs文件系统模块
2016/12/08 Javascript
javascript中闭包概念与用法深入理解
2016/12/15 Javascript
Vue页面跳转动画效果的实现方法
2018/09/23 Javascript
使用VUE实现在table中文字信息超过5个隐藏鼠标移到时弹窗显示全部
2019/09/16 Javascript
[01:43]3.19DOTA2发布会 三代刀塔人第三代
2014/03/25 DOTA
[01:39:04]DOTA2-DPC中国联赛 正赛 SAG vs CDEC BO3 第二场 2月1日
2021/03/11 DOTA
[08:08]DOTA2-DPC中国联赛2月28日Recap集锦
2021/03/11 DOTA
python字典基本操作实例分析
2015/07/11 Python
python数组过滤实现方法
2015/07/27 Python
python DataFrame获取行数、列数、索引及第几行第几列的值方法
2018/04/08 Python
python 随机生成10位数密码的实现代码
2019/06/27 Python
Python super()方法原理详解
2020/03/31 Python
Python3以GitHub为例来实现模拟登录和爬取的实例讲解
2020/07/30 Python
La Senza官网:北美顶尖性感内衣品牌
2018/08/03 全球购物
Athleta官网:购买女士瑜伽服、技术运动服和休闲运动服
2020/11/12 全球购物
写出一个方法实现冒泡排序
2016/07/08 面试题
大学生2014全国两会学习心得体会
2014/03/10 职场文书
销售会计岗位职责
2014/03/15 职场文书
民用住房租房协议书
2014/10/29 职场文书
出纳试用期自我评价
2015/03/10 职场文书
为什么代码规范要求SQL语句不要过多的join
2021/06/23 MySQL
python如何为list实现find方法
2022/05/30 Python