Open loadlj opened 7 years ago
在Pyhton中最常见的with语法打开一个文件:
with open('context_managers.txt', 'r') as infile: print infile
不使用with:
infile = open('context_managers.txt', 'r') print infile infile.close()
with的作用就是不需要你去调用close方法,它会自动帮你去调用close()。比如我们不使用with的时候去操作文件io时可能会碰到一些异常,我们就需要使用try...except...finally这种复杂的方式去处理异常:
try: infile = open('context_managers.txt', 'r') raise Exception("some unknown error occur") except Exception, e: pass finally: infile.close()
with就相当于是上下文管理器(context managers), 调用with的时候就相当于声明了一个函数。它包含两个方法__enter__()和__exit__(), 当我们调用with xxx as xxx的时候就相当于调用__enter__()打开了一个文件描述符,当整个with函数结束的时候,调用__exit__()方法去关闭文件描述符。
__enter__()
__exit__()
with xxx as xxx
class file_open(): def __init__(self, filename, mode): self.filename = filename self.mode = mode def __enter__(self): self.open_file = open(self.filename, self.mode) return self.open_file def __exit__(self, *args): self.open_file.close() with file_open('foo.txt', 'w') as infile: pass
contextlib是用来操作上下文管理器的,可以使用一个简单的语法@contextmanager去声明一个上下文管理器,使用时必须要带有yield关键字。这里的yield就相当于上面提到的__enter__()和__exit__()分界线,在yield之前的部分都可以认为是__enter___()里边的代码,在其之后的都认为是__exit__()方法。
__enter___()
from contextlib import contextmanager @contextmanager def file_open(file_name, mode): open_file = open(file_name, mode) yield open_file open_file.close() with file_open('foo.txt', 'w') as infile: pass
python的官方文档也有一个例子:
from contextlib import contextmanager @contextmanager def tag(name): print("<%s>" % name) yield print("</%s>" % name) with tag("test"): print("foo")
output:
<test> foo </test>
参考来源
Python 中的Context Managers
with语法
在Pyhton中最常见的with语法打开一个文件:
不使用with:
with的作用就是不需要你去调用close方法,它会自动帮你去调用close()。比如我们不使用with的时候去操作文件io时可能会碰到一些异常,我们就需要使用try...except...finally这种复杂的方式去处理异常:
with就相当于是上下文管理器(context managers), 调用with的时候就相当于声明了一个函数。它包含两个方法
__enter__()
和__exit__()
, 当我们调用with xxx as xxx
的时候就相当于调用__enter__()
打开了一个文件描述符,当整个with函数结束的时候,调用__exit__()
方法去关闭文件描述符。contextlib库
contextlib是用来操作上下文管理器的,可以使用一个简单的语法@contextmanager去声明一个上下文管理器,使用时必须要带有yield关键字。这里的yield就相当于上面提到的
__enter__()
和__exit__()
分界线,在yield之前的部分都可以认为是__enter___()
里边的代码,在其之后的都认为是__exit__()
方法。python的官方文档也有一个例子:
output:
参考来源