上下文管理器的任务是:代码块执行前准备,代码块执行后收拾

1 如何使用上下文管理器:

打开一个文件,并写入"hello world"

filename="my.txt"
mode="w"
f=open(filename,mode)
f.write("hello world")
f.close()

当发生异常时(如磁盘写满),就没有机会执行第5行。当然,我们可以采用try-finally语句块进行包装:

writer=open(filename,mode)
try:
writer.write("hello world")
finally:
writer.close()

当我们进行复杂的操作时,try-finally语句就会导致代码不易读,采用with语句重写:

with open(filename,mode) as writer:
writer.write("hello world")

2 自定义上下文管理器

with语句的作用类似于try-finally,提供一种上下文机制。要应用with语句的类,其内部必须提供两个内置函数__enter__和__exit__。前者在主体代码执行前执行,后者在主体代码执行后执行。as后面的变量,是在__enter__函数中返回的。

class echo():
def output(self):
print "hello world"
def __enter__(self):
print "enter"
return self #可以返回任何希望返回的东西
def __exit__(self,exception_type,value,trackback):
print "exit"
if exception_type==ValueError:
return True
else:
return Flase >>>with echo as e:
e.output() 输出:
enter
hello world
exit

3 contextlib模块 

contextlib模块的作用是提供更易用的上下文管理器,它是通过Generator实现的。contextlib中的contextmanager作为装饰器来提供一种针对函数级别的上下文管理机制,常用框架如下:

from contextlib import contextmanager
@contextmanager
def make_context():
print 'enter'
try:
yield "ok"
except RuntimeError,err:
print 'error',err
finally:
print 'exit' >>>with make_context() as value:
print value 输出为:
enter
ok
exit

其中,yield写入try-finally中是为了保证异常安全(能处理异常)as后的变量的值是由yield返回。yield前面的语句可看作代码块执行前操作,yield之后的操作可以看作在__exit__函数中的操作。

file类直接支持上下文管理器API,但有些表示打开句柄的对象并不支持,如urllib.urlopen()返回的对象。还有些遗留类,使用close()方法而不支持上下文管理器API。为了确保关闭句柄,需要使用closing()为它创建一个上下文管理器(调用类的close方法)。

最新文章

  1. MySQL排序原理与案例分析
  2. 干掉命令行窗口下MySql乱码
  3. 微服务实战(二):使用API Gateway--转
  4. HTML5的入门与深入理解
  5. 事故记录:php-cgi进程过多导致系统资源耗尽
  6. Centos 安装vsftpd 服务器
  7. SLAM中的EKF,UKF,PF原理简介
  8. Java用WebSocket + tail命令实现Web实时日志
  9. 自定义ExpressionBuilder
  10. java事务管理(二)
  11. VS2010的openssl源码编译方法
  12. cf478C Table Decorations
  13. 201521123115 《Java程序设计》第3周学习总结
  14. [Micropython]TPYBoard v10x拼插编程实验 点亮心形点阵
  15. log4j的一些配置
  16. HTTP和SOAP完全就是两个不同的协议
  17. JAVAEE期末项目------文章发布系统
  18. oday获取系统最高权限的代码
  19. CodeForces - 754D
  20. Linux From Scratch [3]

热门文章

  1. ES6深入浅出-3 三个点运算 & 新版字符串-1.函数与对象的语法糖
  2. [译]如何在GitHub仓库创建一个标签tag, 并推送到远程分支?
  3. Linux记录-史上最全的MySQL高性能优化实战总结(转载)
  4. 01点睛Spring MVC 4.1-搭建环境
  5. Consul 快速入门 - Kong最佳实践
  6. k8s 使本地集群支持 LoadBalancer 服务
  7. __iter__方法demo
  8. 在linux上cuda9.0 cudnn7.* 安装python3.6 tensorflow 1.5.1
  9. Python3之字符串格式化format函数详解(上)
  10. Tomcat报错:No result type specified for result named 'success'