简介html
with是从2.5版本引入的一个语法. 这个语法自己是为了解决try..finally繁琐的释放各种资源(文件句柄, Lock等)的问题.python
若是想在旧版本中使用这个功能, 直接引入future模块就能够.c++
from __future__ import with_statement
举例简单说明一下没有with和有with的代码区别sql
try: dict_file = open("dict_file_path") for line in dict_file: print line, # do something finally: dict_file.close()
用with-statement的方式以下数据库
with open("dict_file_path") as dict_file: for line in dict_file: print line, # do something
明显使用了with以后语法更加简洁.express
官方对于with-statement的定义以下session
with_stmt ::= "with" with_item ("," with_item)* ":" suite with_item ::= expression ["as" target]
从定义中, 咱们能够看出, 若是想经过with使用多个资源的话, 能够使用下面的写法app
with open("d1_file") as d1, open("d2_file") as d2:
as部分是无关紧要的, 对于lock等这类资源来讲通常都是这种用法函数
我的认为, with-statement是如今带有内存管理语言的折中处理方法, 对于c++来讲, 能够使用RAII的方式, 一个类有明确的析构函数, 在超出做用域以后会被调用, 在析构函数内进行资源的释放是很是不错的选择. 也体现了c++的高效, 灵活和优雅.性能
Java, python这类语言都没法作到, 可是语言自身的异常机制都很是完善, 不像c++为了兼容c致使异常机制显得有点鸡肋. try..catch..finally就成为了这类语言用来进行资源释放的方式, GC(垃圾回收)回收内存的时间不肯定, 没法利用RAII.
With-statement Magic Method
python语言层面上对于with的支持是经过magic method来实现的, 和通常的python特性同样.
使用PEP343中with-statement的定义来引入这两个magic method
with VAR = EXPR: BLOCK
直接翻译过来就是
VAR = EXPR VAR.__enter__() try: BLOCK finally: VAR.__exit__()
咱们能够清楚的看到这两个magic method分别是__enter__和__exit__, 一个在进入with-statement block的时候初始化, 一个在离开的时候进行cleanup工做.
下面来举一个简单的timer例子.
import time class Timer(object): def __init__(self): pass def __enter__(self): self.start = time.time() def __exit__(self, exception_type, exception_val, trace): print "elapsed:", time.time() - self.start if __name__ == "__main__": with Timer(): [i for i in xrange(10000000)]
运行结果以下:
elapsed: 1.32907581329
timer是一个简单实用的类, 在编写性能测试代码的时候, 常常会用到.
水平有限, 欢迎拍砖!
2014.4.19 添加一个with带有异常处理的demo
以一个操做数据库的session为例, 下面的方式能够替代繁琐的try...except...finally语句, 能够包装sqlalchemy的session.
笔者用这个简单的封装做为sqlalchemy来方便处理session相关的操做. commit操做须要本身去调用, 也能够加入到exit方法中.
class Wrapper(object): '''A context manager to automatically close an object with a close method in a with statement.''' def __init__(self, obj): self.obj = obj def __enter__(self): return self.obj # bound to target def __exit__(self, exception_type, exception_val, trace): if exception_type: try: self.obj.rollback() except AttributeError: # obj cannot rollback return True # exception handled successfully try: self.obj.close() except AttributeError: # obj isn't closable return True # exception handled successfully
参考文献: