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中操作字典之clear()方法的使用
May 21 Python
使用python 和 lint 删除项目无用资源的方法
Dec 20 Python
python通过配置文件共享全局变量的实例
Jan 11 Python
Python中按值来获取指定的键
Mar 04 Python
基于python生成器封装的协程类
Mar 20 Python
python实现移位加密和解密
Mar 22 Python
10款最好的Python开发编辑器
Jul 03 Python
Python 装饰器原理、定义与用法详解
Dec 07 Python
python 装饰器的使用示例
Oct 10 Python
Python中基础数据类型 set集合知识点总结
Aug 02 Python
python字符串拼接.join()和拆分.split()详解
Nov 23 Python
PyTorch中permute的使用方法
Apr 26 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判断正常访问和外部访问的示例
2014/02/10 PHP
js string 转 int 注意的问题小结
2013/08/15 Javascript
为指定的元素添加遮罩层的示例代码
2014/01/15 Javascript
jQuery中(function($){})(jQuery)详解
2015/07/15 Javascript
JavaScript学习笔记(三):JavaScript也有入口Main函数
2015/09/12 Javascript
jQuery实现选项卡切换效果简单演示
2015/12/09 Javascript
学习JavaScript设计模式之装饰者模式
2016/01/19 Javascript
20分钟轻松创建自己的Bootstrap站点
2016/05/12 Javascript
完美解决js传递参数中加号和&amp;号自动改变的方法
2016/10/11 Javascript
jQuery动态生成Bootstrap表格
2016/11/01 Javascript
jQuery中animate的几种用法与注意事项
2016/12/12 Javascript
SpringMVC简单整合Angular2的示例
2017/07/31 Javascript
使用jQuery实现鼠标点击左右按钮滑动切换
2017/08/04 jQuery
weex slider实现滑动底部导航功能
2017/08/28 Javascript
AngularJS中下拉框的基本用法示例
2017/10/11 Javascript
vue实现未登录跳转到登录页面的方法
2018/07/17 Javascript
vue实现多个元素或多个组件之间动画效果
2018/09/25 Javascript
微信小程序如何调用新闻接口实现列表循环
2019/07/02 Javascript
[47:36]Optic vs Newbee 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python字符串和文件操作常用函数分析
2015/04/08 Python
Python 处理图片像素点的实例
2019/01/08 Python
Python3.5内置模块之os模块、sys模块、shutil模块用法实例分析
2019/04/27 Python
Python基础学习之类与实例基本用法与注意事项详解
2019/06/17 Python
python对文件目录的操作方法实例总结
2019/06/24 Python
一文轻松掌握python语言命名规范规则
2020/06/18 Python
django restframework serializer 增加自定义字段操作
2020/07/15 Python
HTML5拍照和摄像机功能实战详解
2019/01/24 HTML / CSS
美国首屈一指的高品质珠宝设计师和零售商:Allurez
2018/01/23 全球购物
瑞典廉价机票预订网站:Seat24
2018/06/19 全球购物
大学生护理专业自荐信
2013/10/03 职场文书
迎八一活动主题
2014/01/31 职场文书
我爱读书演讲稿
2014/05/07 职场文书
团队口号大全
2014/06/06 职场文书
党支部三严三实对照检查材料思想汇报
2014/09/29 职场文书
活着观后感
2015/06/03 职场文书
初中数学教学反思范文
2016/02/17 职场文书