http://www.cnblogs.com/coser/archive/2013/01/28/2880328.html

上下文管理协议为代码块提供包含初始化和清理操作的上下文环境。即便代码块发生异常,清理操作也会被执行。

Context对象

*__enter__:初始化环境,返回上下文对象

*__exit__:执行清理操作。返回True时,将阻止异常向外传递

#!/usr/bin/env python26
#-*- coding:utf-8 -*- class MyContext(object):
def __init__(self,*args):
self._data = args
def __enter__(self):
print "__enter__"
return self._data #不一定要返回上下文对象自身 def __exit__(self,exc_type,exc_value,traceback):
if exc_type:
print "Exception:",exc_value
print "__exit__" return True#阻止异常向外传递
with MyContext(1,2,3) as data: #将__enter__返回的对象赋给data
print data
print '*'*30 with MyContext(1,2,3): #发生异常,显示并拦截
raise Exception("data error!") 输出:

__enter__
(1, 2, 3)
__exit__
******************************
__enter__
Exception: data error!
__exit__

上面的模式,需要重写__enter__和__exit__,比较麻烦。contextlib可以解决这个问题。

contextlib

标准库contextlib提供一个contextmanager装饰器,用来简化上下文类型开发。

#!/usr/bin/env python26
#-*- coding: utf-8 -*- from contextlib import contextmanager @contextmanager
def closing(o):
print "__enter__"
yield o print "__exit__"
o.close() with closing(open("readme.txt","r")) as f:
print f.readline(),

contextmanger替我们创建Context对象,并利用yield切换执行过程。

*通过__enter__调用closing函数,将yield结果作为__enter__返回值

*yield让出closing执行权限,转而执行with代码块

*执行完毕,__exit__发生消息,通知yield恢复执行closing后续代码

contextmanger让我们少写很多代码,因为不是自己写__exit__,所以得额外处理异常。

上下文管理协议的用途很广,比如:

1、Synchronized:为代码块提供lock/unlock线程同步;

2、DBContext:为代码块中的逻辑提供共享的数据库连接,并负责关闭连接。

此处先记着,待等到实际应用的时候再更新相关的理解。

具体的例子

1、计算函数的执行时间:

import time

class Context(object):

    def __init__(self):
self.start = None
self.end = None def __enter__(self):
self.start = time.time()
print "Start"
return self def __exit__(self, exctype, excvalue, traceback):
print "exit"
self.end = time.time() print "End:"
print 'Cost:%d' % (self.end - self.start)
return self def test():
return Context() with test():
print 'int test'
time.sleep(2)

  

输出结果:

Start
int test
exit
End:
Cost:2

 

2、使用装饰器的方式

#在装饰器内部使用with语法
def with_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
with Context():
return func(*args, **kwargs)
return wrapper @with_decorator
def test_decorator():

  

  

 

Python之上下文管理的更多相关文章

  1. Python之上下文管理器

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #Python之上下文管理器 #http://python.jobbole.com/82620/ #语法形式: ...

  2. python之上下文管理、redis的发布订阅、rabbitmq

    使用with打开文件的方式,是调用了上下文管理的功能 #打开文件的两种方法: f = open('a.txt','r') with open('a.txt','r') as f 实现使用with关闭s ...

  3. python基础之上下文管理器

    前言 关于计算器运行的上下文的概念,我的理解也不是很深:按我的理解就是程序在运行之前,其所需要的资源,运行环境等都会被序列化,然后加入到CPU的任务队列中,等待调度系统分配时间片执行.下面谈谈pyth ...

  4. Flask之上下文管理机制

    前引 在了解flask上下文管理机制之前,先来一波必知必会的知识点. 面向对象双下方法 首先,先来聊一聊面向对象中的一些特殊的双下划线方法,比如__call__.__getattr__系列.__get ...

  5. flask之上下文管理

    简单来说,falsk上下文管理可以分为三个阶段: 1.请求进来时,将请求鞋底的相关数据放入上下文管理中进行管理 2.在视图函数中,要去上下文管理中取值 3.请求响应之后,要将上下文管理中的数据清除 详 ...

  6. .Net组件程序设计之上下文

    .Net组件程序设计之上下文 在后续篇幅的远程调用的文章里有说到应用程序域,那是大粒度的控制程序集的逻辑存在,那么想对对象的控制又由谁来做主呢?没错了,就是上下文.CLR把应用程序域更细化了,在应用程 ...

  7. flask源码解析之上下文为什么用栈

    楔子 我在之前的文章<flask源码解析之上下文>中对flask上下文流程进行了详细的说明,但是在学习的过程中我一直在思考flask上下文中为什么要使用栈完成对请求上下文和应用上下文的入栈 ...

  8. python 黑魔法 ---上下文管理器(contextor)

    所谓上下文 计算机上下文(Context)对于我而言,一直是一个很抽象的名词.就像形而上一样,经常听见有人说,但是无法和现实认知世界相结合. 最直观的上下文,莫过于小学的语文课,经常会问联系上下文,推 ...

  9. Python的包管理工具

    Python的包管理工具 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.为什么使用包管理 Python的模块或者源文件直接可以复制到目标项目目录中,就可以导入使用了. 但是为了 ...

随机推荐

  1. PS+HTML测试

    PS: 1. 写出标尺.参考线.网格线.放大和缩小的快捷键 2. 写出RGB模式和CMYK颜色模式里每一个字母代表什么颜色 3. 写出暖色和冷色各3种 4. 写出常用的抠图工具(6个以上) 5. 写出 ...

  2. ListBox数据绑定无效

    public class DataList { public List<string> listSource; private DataTable table; public DataLi ...

  3. ubuntu6.04下安装Eclipse for C/C++ Development

    ubuntu6.04下安装Eclipse for C/C++ Development 首先安装gcc/g++ 需要安装jdk,有的可以尝试安装openjdk. sudo apt-get install ...

  4. 基于HTML5和WebGL的碰撞测试

    这是公司大神写的一个放官网上给用户学习的例子,我一开始真的不知道这是在干嘛,就只是将三个形状图元组合在一起,然后可以同时旋转.放大缩小这个三个图形,点击"Animate"就能让中间 ...

  5. 无限大地图:lightmap拆分

    无缝地图涉及到地形.物件的分块加载,同样,lightmap也需要动态加载.而场景烘焙时,所有物件都是一起烘焙的,那怎么把某些物件指定烘焙到某一张lightmap贴图中?网上找了很久,也没有看到具体的实 ...

  6. javascript面向对象的写法及jQuery面向对象的写法

    文章由来:jQuery源码学习时的总结 在JS中,一般的面向对象的写法如下: function Cao(){}//定义一个构造函数 Cao.prototype.init = function(){}/ ...

  7. UVa11212,Editing a Book

    正如书上所说,本题需要用IDA*算法求解 启发函数是3d+h>3maxd(d为当前操作步骤数,h为当前逆序对数,maxd为当前枚举的最大步骤数) 可见迭代递归的核心思想是枚举ans去dfs是否可 ...

  8. SpringMVC + Spring + Mybatis+ Redis +shiro以及MyBatis学习

    SpringMVC + Spring + Mybatis+ Redis +shiro http://www.sojson.com/shiro MyBatis简介与配置MyBatis+Spring+My ...

  9. kafka 的 createDirectStream

    一入大数据深似海,脑袋不够用了,先留下只言片语. kafka api中给出2类直接获取流的接口:createStream和createDirectStream. createStream比较简单,只需 ...

  10. (MariaDB)MySQL数据类型详解和存储机制

    html { font-family: sans-serif } body { margin: 0 } article,aside,details,figcaption,figure,footer,h ...