文档章节

Python深入上下文管理器

小致Daddy
 小致Daddy
发布于 2016/07/14 21:17
字数 889
阅读 61
收藏 0

码上生花,ECharts 作品展示赛正式启动!>>>

上下文管理器(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的闭包
小致Daddy

小致Daddy

粉丝 208
博文 604
码字总数 622330
作品 0
济南
技术主管
私信 提问
加载中
请先登录后再评论。
深入理解协程(四):async/await异步爬虫实战

本文目录: 同步方式爬取博客标题 async/await异步爬取博客标题 本片为深入理解协程系列文章的补充。 你将会在从本文中了解到:如何运用的实际的爬虫中。 案例 从CSDN上批量爬取指定文章的标...

osc_i05nmotv
01/18
6
0
Supporting Python 3(支持python3)——使用现代的风格改善你的代码

使用现代风格改善你的代码 原文: http://python3porting.com/improving.html 译者: TheLover_Z 一旦你开始使用 Python 3,你就有机会接触新的特性来改善你的代码。这篇文章中提到的很多东西...

在湖闻樟
2015/10/26
142
0
深入理解 Python 中的上下文管理器

提示:前面的内容较为基础,重点知识在后半段。 这个关键字,对于每一学习Python的人,都不会陌生。 操作文本对象的时候,几乎所有的人都会让我们要用 ,这就是一个上下文管理的例子。你一定...

osc_8vgjpfw9
2019/03/12
4
0
经典7大Python面试题!看完考官竟然给了我50k的薪资

  Python面试(一)之交换变量值   平时时不时会面面实习生,大多数的同学在学校里都已经掌握了Python。面试的时候要求同学们实现一个简单的函数,交换两个变量的值,大多数的同学给出的...

菜鸟学Python
2018/08/07
0
0
第三章:Python高级编程-深入类和对象

第三章:Python高级编程-深入类和对象 Python3高级核心技术97讲 笔记 3.1 鸭子类型和多态 3.2 抽象基类(abc模块) 3.3 使用instance而不是type 3.4 类变量和对象变量 3.5 类属性和实例属性以...

coderchen01
05/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

JeecgBoot 连接达梦数据库

JeecgBoot连接达梦数据库 一、达梦数据库官网下载地址 http://www.dameng.com/down.aspx?TypeId=11&FId=t14:11:14 项目采用DMB8开发版(windows64位) 二、需要两个jar,可在达梦数据库安装...

JEECG开源社区
今天
26
0
迅捷CAD转换器好不好用?

大家在工作中有掌握一些必备的CAD小技巧吗?比如怎么实现DWG与DXF互转?我们应该使用什么工具?下面小张给大家带来一款实用软件(迅捷CAD转换器)的图文教程分享,有兴趣和有需要的小伙伴们仔...

逆风小师傅
今天
19
0
gitee仓库管理入门

gitee就是码云。只是入门笔记。 1.gitee注册,git下载安装。这个简单就不说了。 查看git配置: git config --list 配置用户名 邮箱 密码 git config --global user.name "用户名"git co...

仙游度尾东峰黄恩赐
今天
17
0
Linux初学之bash相关

bash的颜色显示规则: ascll编码对于颜色进行设置 \033: ctrl键 [ :控制字符和颜色代码之间的间隔字符 0m:关闭颜色属性的命令 1m:对于显示的文本字符进行加粗 4m:为文本字符加下划线标识...

osc_umiwij2c
今天
19
0
linux初学之——权限管理

上篇已经提到用户和组的管理相关知识,我们已经学会了如何在Linux系统中创建了用户和组,并对用户和组的内容和属性做一些修改。但是我们知道Linux系统是多用户多任务的操作系统,多个合法用户...

osc_znv7pwo3
今天
23
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部