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中的hashlib和base64加密模块使用实例
Sep 02 Python
基于python神经卷积网络的人脸识别
May 24 Python
Python使用numpy模块创建数组操作示例
Jun 20 Python
python 对给定可迭代集合统计出现频率,并排序的方法
Oct 18 Python
python3.6使用urllib完成下载的实例
Dec 19 Python
对Python捕获控制台输出流的方法详解
Jan 07 Python
win8.1安装Python 2.7版环境图文详解
Jul 01 Python
python matplotlib如何给图中的点加标签
Nov 14 Python
python 已知一个字符,在一个list中找出近似值或相似值实现模糊匹配
Feb 29 Python
Pytorch使用PIL和Numpy将单张图片转为Pytorch张量方式
May 25 Python
在pycharm中debug 实时查看数据操作(交互式)
Jun 09 Python
Python实现排序方法常见的四种
Jul 15 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
三国漫画《火凤燎原》宣布动画化PV放出 预计2020年播出
2020/03/08 国漫
PHPnow安装服务[apache_pn]失败的问题的解决方法
2010/09/10 PHP
php读取富文本的时p标签会出现红线是怎么回事
2014/05/13 PHP
PHP通过插入mysql数据来实现多机互锁实例
2014/11/05 PHP
PHP使用header()输出图片缓存实例
2014/12/09 PHP
php构造函数的继承方法
2015/02/09 PHP
PHP回调函数与匿名函数实例详解
2017/08/16 PHP
JavaScript 异步调用框架 (Part 6 - 实例 &amp; 模式)
2009/08/04 Javascript
简单几行JS Code实现IE邮件转发新浪微博
2013/07/03 Javascript
javascript实例--教你实现扑克牌洗牌功能
2014/05/15 Javascript
javascript最基本的函数汇总
2015/06/25 Javascript
JavaScript编程中布尔对象的基本使用
2015/10/25 Javascript
超实用的JavaScript代码段 附使用方法
2016/05/22 Javascript
Bootstrap 3浏览器兼容性问题及解决方案
2017/04/11 Javascript
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解
2019/12/07 Javascript
JS数组reduce()方法原理及使用技巧解析
2020/07/14 Javascript
Vue filter 过滤器、以及在table中的使用介绍
2020/09/07 Javascript
[16:21]教你分分钟做大人:圣堂刺客
2014/12/03 DOTA
[01:18:35]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第一场 1月29日
2021/03/11 DOTA
简单的抓取淘宝图片的Python爬虫
2014/12/25 Python
简析Python的闭包和装饰器
2016/02/26 Python
python 获取当天凌晨零点的时间戳方法
2018/05/22 Python
numpy.ndarray 交换多维数组(矩阵)的行/列方法
2018/08/02 Python
Python + OpenCV 实现LBP特征提取的示例代码
2019/07/11 Python
Python如何创建装饰器时保留函数元信息
2020/08/07 Python
施华洛世奇德国官网:SWAROVSKI德国
2017/02/01 全球购物
FC-Moto瑞典:欧洲最大的摩托车服装和头盔商店之一
2018/11/27 全球购物
零件设计自荐信范文
2013/11/27 职场文书
大学生标准自荐书
2014/06/15 职场文书
高中生思想道德自我评价
2015/03/09 职场文书
公司联欢会主持词
2015/07/04 职场文书
安全生产协议书
2016/03/22 职场文书
Html5通过数据流方式播放视频的实现
2021/04/27 HTML / CSS
Python OpenCV超详细讲解调整大小与图像操作的实现
2022/04/02 Python
SpringBoot全局异常处理方案分享
2022/05/25 Java/Android
了解MySQL查询语句执行过程(5大组件)
2022/08/14 MySQL