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列表计数及插入实例
Dec 17 Python
简单总结Python中序列与字典的相同和不同之处
Jan 19 Python
Python利用Beautiful Soup模块修改内容方法示例
Mar 27 Python
完美解决python中ndarray 默认用科学计数法显示的问题
Jul 14 Python
python中redis查看剩余过期时间及用正则通配符批量删除key的方法
Jul 30 Python
Python实现监控键盘鼠标操作示例【基于pyHook与pythoncom模块】
Sep 04 Python
在macOS上搭建python环境的实现方法
Aug 13 Python
用python实现英文字母和相应序数转换的方法
Sep 18 Python
用Python实现校园通知更新提醒功能
Nov 23 Python
Linux下升级安装python3.8并配置pip及yum的教程
Jan 02 Python
Python如何获取文件路径/目录
Sep 22 Python
Python接口自动化系列之unittest结合ddt的使用教程详解
Feb 23 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
将酷狗krc歌词解析并转换为lrc歌词php源码
2014/06/20 PHP
PHP基于rabbitmq操作类的生产者和消费者功能示例
2018/06/16 PHP
location.href语句与火狐不兼容的问题
2010/07/04 Javascript
JS操作数据库的实例代码
2013/10/17 Javascript
js中substr,substring,indexOf,lastIndexOf的用法小结
2013/12/27 Javascript
Jquery获取元素的父容器对象示例代码
2014/02/10 Javascript
js判断上传文件类型判断FileUpload文件类型代码
2014/05/20 Javascript
javascript实现切换td中的值
2014/12/05 Javascript
AngularJS使用ngMessages进行表单验证
2015/12/27 Javascript
Js查找字符串中出现次数最多的字符及个数实例解析
2016/09/05 Javascript
jQuery内容过滤选择器用法示例
2016/09/09 Javascript
HTML5 js实现拖拉上传文件功能
2020/11/20 Javascript
JS工厂模式开发实践案例分析
2019/10/17 Javascript
JS Web Flex弹性盒子模型代码实例
2020/03/10 Javascript
JavaScript实现京东快递单号查询
2020/11/30 Javascript
python模拟登录百度代码分享(获取百度贴吧等级)
2013/12/27 Python
对python中的乘法dot和对应分量相乘multiply详解
2018/11/14 Python
Python设计模式之组合模式原理与用法实例分析
2019/01/11 Python
CSS3动画特效在活动页中的应用
2020/01/21 HTML / CSS
HTML5 FileReader对象的具体使用方法
2020/05/22 HTML / CSS
韩国CJ食品专卖网:CJonmart
2016/09/11 全球购物
乌克兰香水和化妆品网站:Notino.ua
2018/03/26 全球购物
Bally巴利中国官网:经典瑞士鞋履、手袋及配饰奢侈品牌
2018/10/09 全球购物
计算机软件个人的自荐信范文
2013/12/01 职场文书
事业单位公务员的职业生涯规划
2014/01/15 职场文书
会计岗位描述
2014/02/22 职场文书
党的群众路线教育实践方案
2014/05/11 职场文书
教师求职信范文
2014/05/24 职场文书
青奥会口号
2014/06/12 职场文书
拒绝黄毒毒宣传标语
2014/06/26 职场文书
税务职业生涯规划书范文
2014/09/16 职场文书
优秀大学生事迹材料
2014/12/24 职场文书
英文版辞职信
2015/02/28 职场文书
小型企业的绩效考核制度模板
2019/11/21 职场文书
JavaScript 反射学习技巧
2021/10/16 Javascript
一篇文章告诉你如何实现Vue前端分页和后端分页
2022/02/18 Vue.js