with
我们打开文件常常使用with,with语句可以帮我们自动关闭文件。这里的关闭文件不仅仅是文件对象的销毁,还包括操作系统文件句柄的释放
当然,不仅仅只有open()函数可以结合with来使用,只要一个对象实现了 enter 和 exit 方法是,那么就能使用with语句
class Database(object):
def __init__(self):
self.connected = False
def __enter__(self):
self.connected = True
print('__enter__')
return self
def __exit__(self, exc_type, exc_value, traceback):
print('__exit__')
self.connected = False
def query(self):
if self.connected:
print('query data')
else:
raise ValueError('DB not connected ')
with Database() as db:
print('进来了')
结果:
__enter__
进来了
__exit__
contextlib
编写 enter 和 exit 仍然很繁琐,因此Python的标准库 contextlib 提供了更简单的写法
不带对象的contextmanager
上下文管理器说白了就是在一个操作执行的前面和后面分别执行一些操作,比如我们想在函数调用前执行一些操作(装饰器也能起到类似的效果)
from contextlib import contextmanager
@contextmanager
def tag(name):
print("<%s>" % name)
yield
print("</%s>" % name)
with tag("h1"):
print("hello")
print("world")
with进来的时候先执行yield之前的代码,然后执行with语句块的代码,最后执行yield之后的代码
带对象的contextmanager
from contextlib import contextmanager
class Query(object):
def __init__(self, name):
self.name = name
def query(self):
print('Query info about %s...' % self.name)
@contextmanager
def create_query(name):
print('Begin')
q = Query(name)
yield q
print('End')
with create_query('Bob') as q:
q.query()