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读取csv文件示例(python操作csv)
Mar 11 Python
Python实现数通设备端口使用情况监控实例
Jul 15 Python
利用aardio给python编写图形界面
Aug 21 Python
python并发编程之线程实例解析
Dec 27 Python
Python编写Windows Service服务程序
Jan 04 Python
快速解决pandas.read_csv()乱码的问题
Jun 15 Python
python通过Windows下远程控制Linux系统
Jun 20 Python
python根据文章标题内容自动生成摘要的实例
Feb 21 Python
分析运行中的 Python 进程详细解析
Jun 22 Python
python脚本当作Linux中的服务启动实现方法
Jun 28 Python
python实现批量修改文件名
Mar 23 Python
python 实现aes256加密
Nov 27 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编程与应用
2006/10/09 PHP
php实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
php通过分类列表产生分类树数组的方法
2015/04/20 PHP
php使用filter_var函数判断邮箱,url,ip格式示例
2019/07/06 PHP
有趣的javascript数组定义方法
2010/09/10 Javascript
文本框(input)获取焦点(onfocus)时样式改变的示例代码
2014/01/10 Javascript
动态的绑定事件addEventListener方法的使用
2014/01/24 Javascript
JS判断浏览器是否支持某一个CSS3属性的方法
2014/10/17 Javascript
JS实现控制表格单元格垂直对齐的方法
2015/03/30 Javascript
js实现字符串和数组之间相互转换操作
2016/01/12 Javascript
浅析BootStrap栅格系统
2016/06/07 Javascript
微信小程序教程之本地图片上传(leancloud)实例详解
2016/11/16 Javascript
vue项目打包后怎样优雅的解决跨域
2019/05/26 Javascript
js实现时钟定时器
2020/03/26 Javascript
vant实现购物车功能
2020/06/29 Javascript
H5+css3+js搭建带验证码的登录页面
2020/10/11 Javascript
[04:48]DOTA2亚洲邀请赛林书豪为VGJ加油
2017/04/01 DOTA
[59:59]EG vs IG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python基础之变量基本用法与进阶详解
2020/01/03 Python
使用python turtle画高达
2020/01/19 Python
详解Python流程控制语句
2020/10/28 Python
Selenium环境变量配置(火狐浏览器)及验证实现
2020/12/07 Python
python RSA加密的示例
2020/12/09 Python
浅谈盘点5种基于Python生成的个性化语音方法
2021/02/05 Python
详解python日志输出使用配置文件格式
2021/02/10 Python
Audible英国:有声读物,30天免费试用
2019/10/16 全球购物
Monica Vinader官网:英国轻奢珠宝品牌
2020/02/05 全球购物
自荐书模板
2013/12/15 职场文书
党支部创先争优承诺书
2014/08/30 职场文书
毕业生评语大全
2015/01/04 职场文书
MySQL如何使用使用Xtrabackup进行备份和恢复
2021/06/21 MySQL
继承Win10缺点!教你关闭Win11烦人的网络搜索
2021/11/23 数码科技
Python实现猜拳与猜数字游戏的方法详解
2022/04/06 Python
Python实现科学占卜 让视频自动打码
2022/04/09 Python
公历12个月名称的由来
2022/04/12 杂记
MySQL外键约束(Foreign Key)案例详解
2022/06/28 MySQL