Python深入学习之上下文管理器


Posted in Python onAugust 31, 2014

上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围。一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存)。它的语法形式是with...as...

关闭文件

我们会进行这样的操作:打开文件,读写,关闭文件。程序员经常会忘记关闭文件。上下文管理器可以在不需要文件的时候,自动关闭文件。

下面我们看一下两段程序:

# without context manager

f = open("new.txt", "w")

print(f.closed)               # whether the file is open

f.write("Hello World!")

f.close()

print(f.closed)

以及:
# with context manager

with open("new.txt", "w") as f:

    print(f.closed)

    f.write("Hello World!")

print(f.closed)

两段程序实际上执行的是相同的操作。我们的第二段程序就使用了上下文管理器 (with...as...)。上下文管理器有隶属于它的程序块。当隶属的程序块执行结束的时候(也就是不再缩进),上下文管理器自动关闭了文件 (我们通过f.closed来查询文件是否关闭)。我们相当于使用缩进规定了文件对象f的使用范围。

上面的上下文管理器基于f对象的__exit__()特殊方法(还记得我们如何利用特殊方法来实现各种语法?参看特殊方法与多范式)。当我们使用上下文管理器的语法时,我们实际上要求Python在进入程序块之前调用对象的__enter__()方法,在结束程序块的时候调用__exit__()方法。对于文件对象f来说,它定义了__enter__()和__exit__()方法(可以通过dir(f)看到)。在f的__exit__()方法中,有self.close()语句。所以在使用上下文管理器时,我们就不用明文关闭f文件了。

自定义

任何定义了__enter__()和__exit__()方法的对象都可以用于上下文管理器。文件对象f是内置对象,所以f自动带有这两个特殊方法,不需要自定义。

下面,我们自定义用于上下文管理器的对象,就是下面的myvow:

# customized object
class VOW(object):

    def __init__(self, text):

        self.text = text

    def __enter__(self):

        self.text = "I say: " + self.text    # add prefix

        return self                          # note: return an object

    def __exit__(self,exc_type,exc_value,traceback):

        self.text = self.text + "!"          # add suffix


with VOW("I'm fine") as myvow:

    print(myvow.text)
print(myvow.text)

我们的运行结果如下:

I say: I'm fine

I say: I'm fine!

我们可以看到,在进入上下文和离开上下文时,对象的text属性发生了改变(最初的text属性是"I'm fine")。

__enter__()返回一个对象。上下文管理器会使用这一对象作为as所指的变量,也就是myvow。在__enter__()中,我们为myvow.text增加了前缀 ("I say: ")。在__exit__()中,我们为myvow.text增加了后缀("!")。

注意: __exit__()中有四个参数。当程序块中出现异常(exception),__exit__()的参数中exc_type, exc_value, traceback用于描述异常。我们可以根据这三个参数进行相应的处理。如果正常运行结束,这三个参数都是None。在我们的程序中,我们并没有用到这一特性。

总结:

通过上下文管理器,我们控制对象在程序不同区间的特性。上下文管理器(with EXPR as VAR)大致相当于如下流程:

# with EXPR as VAR:
VAR = EXPR

VAR = VAR.__enter__()

try:

    BLOCK

finally:

    VAR.__exit__()

由于上下文管理器带来的便利,它是一个值得使用的工具。
Python 相关文章推荐
Python标准库defaultdict模块使用示例
Apr 28 Python
python3爬取淘宝信息代码分析
Feb 10 Python
Python Tkinter模块实现时钟功能应用示例
Jul 23 Python
python实现字符串加密成纯数字
Mar 19 Python
OpenCV搞定腾讯滑块验证码的实现代码
May 18 Python
Python 循环终止语句的三种方法小结
Jun 24 Python
Python Opencv任意形状目标检测并绘制框图
Jul 23 Python
Python使用import导入本地脚本及导入模块的技巧总结
Aug 07 Python
Python可以实现栈的结构吗
May 27 Python
keras.utils.to_categorical和one hot格式解析
Jul 02 Python
python 算法题——快乐数的多种解法
May 27 Python
python 远程执行命令的详细代码
Feb 15 Python
Python深入学习之特殊方法与多范式
Aug 31 #Python
python中的reduce内建函数使用方法指南
Aug 31 #Python
Python中使用ConfigParser解析ini配置文件实例
Aug 30 #Python
python进阶教程之动态类型详解
Aug 30 #Python
python进阶教程之异常处理
Aug 30 #Python
python进阶教程之函数对象(函数也是对象)
Aug 30 #Python
python进阶教程之循环对象
Aug 30 #Python
You might like
PHP编程网上资源导航
2006/10/09 PHP
PHP 设置MySQL连接字符集的方法
2011/01/02 PHP
php学习之 数组声明
2011/06/09 PHP
深入分析使用mysql_fetch_object()以对象的形式返回查询结果
2013/06/05 PHP
PHP内置过滤器FILTER使用实例
2014/06/25 PHP
php函数mkdir实现递归创建层级目录
2016/10/27 PHP
yii2.0整合阿里云oss的示例代码
2017/09/19 PHP
一个对于js this关键字的问题
2007/01/09 Javascript
关于viewport,Ext.panel和Ext.form.panel的关系
2009/05/07 Javascript
JQuery实现动态添加删除评论的方法
2015/05/18 Javascript
微信小程序 网络API Websocket详解
2016/11/09 Javascript
javascript中Date对象的使用总结
2016/11/21 Javascript
JavaScript面向对象分层思维全面解析
2016/11/22 Javascript
vue中用H5实现文件上传的方法实例代码
2017/05/27 Javascript
jquery实现点击弹出对话框
2020/02/08 jQuery
javascript贪吃蛇游戏设计与实现
2020/09/17 Javascript
[53:18]Spirit vs Liquid Supermajor小组赛A组 BO3 第三场 6.2
2018/06/03 DOTA
Python中itertools模块用法详解
2014/09/25 Python
Python实现文件按照日期命名的方法
2015/07/09 Python
在Python web中实现验证码图片代码分享
2017/11/09 Python
python实现的分层随机抽样案例
2020/02/25 Python
python微信公众号开发简单流程实现
2020/03/09 Python
解决运行出现'dict' object has no attribute 'has_key'问题
2020/07/15 Python
雅高酒店中国:Accorhotels.com China
2018/03/26 全球购物
MADE法国:提供原创设计师家具
2018/09/18 全球购物
可持续未来的时尚基础:Alternative Apparel
2019/05/06 全球购物
Eton丹麦官网:精美的男式衬衫
2020/05/27 全球购物
C#中有没有运算符重载?能否使用指针?
2014/05/05 面试题
解释i节点在文件系统中的作用
2013/11/26 面试题
科技工作者先进事迹
2014/08/16 职场文书
某集团股份有限公司委托书样本
2014/09/24 职场文书
党性分析材料格式
2014/12/19 职场文书
假如给我三天光明读书笔记
2015/06/26 职场文书
2015初中团委工作总结
2015/07/28 职场文书
React 并发功能体验(前端的并发模式)
2021/07/01 Javascript
win10键盘驱动怎么修复?Win10键盘驱动修复小技巧
2022/04/06 数码科技