上下文管理器就是实现了上下文协议的类
上下文协议就是一个类要实现__enter__()和__exit__()两个方法
Python提供了With语句语法,来构建对资源创建与释放的语法糖
优秀实践:
class Database(object):
...
def __enter__(self):
self.connect()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
def handle_query():
with Database() as db:
result = db.query()
with语句的基本语法结构如下:
with expression [as variable]:
with-block
with语句的expression是上下文管理器
variable是上下文管理器expression调用__enter__()函数返回的对象
with-block是执行语句,with-block执行完毕时,
with语句会自动进行资源清理,下面例子with语句会自动关闭文件
调用__exit__()方法时,如果是with语句体造成的异常退出,那异常类型、异常值、异常追踪信息将被传给__exit__(),
如果在exit函数最后执行return True:那么异常就不会向外抛出,
默认返回false,向外抛出异常信息,程序退出
实例:
class SimpleObj:
def __enter__(self): # 获取资源
print("enter")
def __exit__(self, exc_type, exc_val, exc_tb): # 释放资源
print("exit")
return True
def said(self):
print("said")
with SimpleObj() as P:
P.said()
执行结果:
class SimpleObj:
def __enter__(self): # 获取资源
print("enter")
def __exit__(self, exc_type, exc_val, exc_tb): # 释放资源
print("exit")
return False
def said(self):
print("said")
with SimpleObj() as P:
P.said()
执行结果:
如常用的打开文件方式:
f = open("test.txt")
try:
for line in f.readlines():
print(line)
finally:
f.close()
等价于以下代码
with open("text.txt") as f:
for line in f.readlines()
print(line)
上下文管理器open("text.txt")的__enter__()函数返回一个文件对象
with语句会自动进行资源清理,自动关闭文件