1.with语句时用于对try except finally 的优化,让代码更加美观,
例如常用的开发文件的操作,用try except finally 实现:
f=open('file_name','r') try: r=f.read() except: pass finally: f.close()
打开文件的时候,为了能正常释放文件的句柄,都要加个try,然后再finally里把f close掉,但是这样的代码不美观,finally就像个尾巴,一直托在后面,尤其是当try里面的语句时几十行
用with的实现:
with open('file_name','r') as f: r=f.read()
这条语句就好简洁很多,当with里面的语句产生异常的话,也会正常关闭文件
2.除了打开文件,with语句还可以用于哪些地方呢?
with只适用于上下文管理器的调用,除了文件外,with还支持 threading、decimal等模块,当然我们也可以自己定义可以给with调用的上下文管理器
2.1使用类定义上下文管理器
class A(): def __enter__(self): self.a=1 return self def f(self): print 'f' def __exit__(self,a,b,c): print 'exit' def func(): return A() with A() as a: 1/0 a.f() print a.a
使用类定义上下文管理器需要在类上定义__enter__和__exit__方法,执行with A() as a: 语句时会先执行__enter__方法,这个方法的返回值会赋值给后面的a变量,当with里面的语句产生异常或正常执行完时,都好调用类中的__exit__方法。
2.2使用生成器定义上下文管理器
from contextlib import contextmanager @contextmanager def demo(): print '这里的代码相当于__enter__里面的代码' yield 'i ma value' print '这里的代码相当于__exit__里面的代码' with demo() as value: print value
2.3 自定义支持 closing 的对象
class closing(object): def __init__(self, thing): self.thing = thing def __enter__(self): return self.thing def __exit__(self, *exc_info): self.thing.close() class A(): def __init__(self): self.thing=open('file_name','w') def f(self): print '运行函数' def close(self): self.thing.close() with closing(A()) as a: a.f()