作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

上下文管理器(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 上下文管理器的更多相关文章

  1. Python 上下文管理器和else块

    最终,上下文管理器可能几乎与子程序(subroutine)本身一样重要.目前,我们只了解了上下文管理器的皮毛--Basic 语言有with 语句,而且很多语言都有.但是,在各种语言中 with 语句的 ...

  2. Python上下文管理器

    在Python中让自己创建的函数.类.对象支持with语句,就实现了上线文管理协议.我们经常使用with open(file, "a+") as f:这样的语句,无需手动调用f.c ...

  3. python上下文管理器ContextLib及with语句

    http://blog.csdn.net/pipisorry/article/details/50444736 with语句 with语句是从 Python 2.5 开始引入的一种与异常处理相关的功能 ...

  4. Python上下文管理器 with

    对于系统资源的操作,如:文件操作.数据库操作等,我们往往打开文件.连接数据库后忘了将其close掉,这时就可能会引发异常,因此我们常用的做法是: # coding:utf-8 f = open(&qu ...

  5. Python上下文管理器(Context managers)

    上下文管理器(Context managers) 上下文管理器允许你在有需要的时候,精确地分配和释放资源. 使用上下文管理器最广泛的案例就是with语句了.想象下你有两个需要结对执行的相关操作,然后还 ...

  6. python上下文管理器细读

    test 1 上下文管理器,将生成器转化为上下文管理器 import contextlib @contextlib.contextmanager def a(): print(1) yield pri ...

  7. 吃透Python上下文管理器

    什么是上下文管理器? 我们常见的with open操作文件,就是一个上下文管理器.如: with open(file, 'rb') as f: text = f.read() 那上下文管理器具体的定义 ...

  8. python 上下文管理器contextlib.ContextManager

    1 模块简介 在数年前,Python 2.5 加入了一个非常特殊的关键字,就是with.with语句允许开发者创建上下文管理器.什么是上下文管理器?上下文管理器就是允许你可以自动地开始和结束一些事情. ...

  9. Python 上下文管理器模块--contextlib

    在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...

随机推荐

  1. 使用kendoui对grid指定行变色

    关键点在于绑定数据源后进行判断,可直接获取当前绑定对象的属性 dataBound: function () { dataView = this.dataSource.view(); ; i < ...

  2. 查看mysql 的物理存储路径

    mysql> show global variables like "%datadir%";

  3. 【翻译习作】 Windows Workflow Foundation程序开发-第一章02

    1.2      Windows Workflow概览 微软的Windows Workflow Foundation(简称WF)是.NET框架3.0版的一部分..NET3.0其它主要部分是Window ...

  4. 【教程】【FLEX】#003 自定义事件、模块间通讯

    本篇笔记,主要阐明 事件是如何创建 和 如何使用自定义事件达到模块之间通讯 的效果. 句子解释: 什么叫做模块之间的通讯呢?? 简单点说,就是两个模块之间可以互相传数据. A模块 可以接收到 B模块的 ...

  5. com学习前提必看

    1) COM组件实际上是一个C++类,而接口都是纯虚类.组件从接口派生而来.我们可以简单的用纯粹的C++的语法形式来描述COM是个什么东西: class IObject { public: virtu ...

  6. vss error reading from file 解决方法

    vss error reading from file 解决方法 1 若服务器中存在 vss/data/backup目录,请将该目录删掉2 运行cmd cd.. cd C:\Program Files ...

  7. 无法读取配置节“protocolMapping”,因为它缺少节声明

    无法读取配置节“protocolMapping”,因为它缺少节声明 1.正常情况   :  Web.config文件中有protocolMapping节点, 发现在IIS部署时使用了.NET 2.0的 ...

  8. Ext.Net 破解

    在使用 Ext.Net 框架时,如果没有得到正版授权(安装密钥),在站点发布后,打开界面总是弹出一个窗口,提示没有授权,看着都头疼,难道一定要安装密钥吗?但还是有办法解决的,在研究时发现,页面中多了两 ...

  9. linux查看内存和回收内存

    清理前内存使用情况 free -m free -g echo 1 > /proc/sys/vm/drop_caches 清理后内存使用情况 free -m

  10. Andriod项目开发实战(2)——JSON和XML的区别

    详情见: 1.http://www.cnblogs.com/SanMaoSpace/p/3139186.html 2.http://www.cnblogs.com/yank/p/4028266.htm ...