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简单实现基数排序算法
May 16 Python
Django中模型Model添加JSON类型字段的方法
Jun 17 Python
Python编程argparse入门浅析
Feb 07 Python
python 对象和json互相转换方法
Mar 22 Python
PyQt5 QListWidget选择多项并返回的实例
Jun 17 Python
python列表推导式操作解析
Nov 26 Python
Python3.6 + TensorFlow 安装配置图文教程(Windows 64 bit)
Feb 24 Python
Pygame的程序开始示例代码
May 07 Python
Python实现发票自动校核微信机器人的方法
May 22 Python
将pycharm配置为matlab或者spyder的用法说明
Jun 08 Python
python判断一个变量是否已经设置的方法
Aug 13 Python
从零开始的TensorFlow+VScode开发环境搭建的步骤(图文)
Aug 31 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 smarty truncate UTF8乱码问题解决办法
2014/06/13 PHP
php计算2个日期的差值函数分享
2015/02/02 PHP
PHP 实现代码复用的一个方法 traits新特性
2015/02/22 PHP
thinkPHP中验证码的简单实现方法
2016/12/05 PHP
PHP数组访问常用方法解析
2020/09/05 PHP
dojo 之基础篇(三)之向服务器发送数据
2007/03/24 Javascript
手机端网页点击链接触发自动拨打或保存电话的示例代码
2014/08/15 Javascript
javascript实现支持移动设备画廊
2015/08/24 Javascript
JS常见问题之为什么点击弹出的i总是最后一个
2016/01/05 Javascript
AngularJS入门(用ng-repeat指令实现循环输出
2016/05/05 Javascript
详解Angular2中的编程对象Observable
2016/09/17 Javascript
深入浅析JS是按值传递还是按引用传递(推荐)
2016/09/18 Javascript
Jquery实现上下移动和排序代码
2016/10/17 Javascript
JS实现仿百度文库评分功能
2017/01/12 Javascript
jquery实现页面加载效果
2017/02/21 Javascript
jQuery is not defined 错误原因与解决方法小结
2017/03/19 Javascript
vue的Virtual Dom实现snabbdom解密
2017/05/03 Javascript
Angular.js中下拉框实现渲染html的方法
2017/06/18 Javascript
详解微信小程序中的页面代码中的模板的封装
2017/10/12 Javascript
使用ajax的post同步执行(实现方法)
2017/12/21 Javascript
Vue.js中的computed工作原理
2018/03/22 Javascript
解决vue select当前value没有更新到vue对象属性的问题
2018/08/30 Javascript
JavaScript创建防篡改对象的方法分析
2018/12/30 Javascript
使用webpack搭建vue项目及注意事项
2019/06/10 Javascript
Node.js学习教程之Module模块
2019/09/03 Javascript
layui table表格数据的新增,修改,删除,查询,双击获取行数据方式
2019/11/14 Javascript
js实现简单五子棋游戏
2020/05/28 Javascript
利用python实现简单的循环购物车功能示例代码
2017/07/05 Python
Python faker生成器生成虚拟数据代码实例
2020/07/20 Python
pycharm激活方法到2099年(激活流程)
2020/09/22 Python
python对 MySQL 数据库进行增删改查的脚本
2020/10/22 Python
外贸业务员求职自荐信分享
2013/09/21 职场文书
公安局负责人查摆问题及整改方案
2014/09/27 职场文书
警察正风肃纪剖析材料
2014/10/16 职场文书
农贸批发市场管理制度
2015/08/07 职场文书
python 多态 协议 鸭子类型详解
2021/11/27 Python