context manager的__enter__和__exit__方法都可以有返回值。__enter__方法的返回值会通过with语句传给调用者,而__exit__方法的返回值是用来控制异常的。本文将介绍__enter__方法。
context manager的一个最重要的应用就是IO操作。这里的IO操作包括文件读写,数据库和网络的连接,进程间通信等。通常一个IO操作不可避免有建立连接,执行操作请求和断开连接三步。我们用下面的一个类来模拟这三个步骤。
class MyFakeConnection:
def open(self):
print "Connection opened"
def request(self):
print "A request sent"
def close(self):
print "Connection closed"
上面的三个步骤中open和close这两个操作是标准的操作,几乎没有任何变化。因此,我们希望能够有一种机制,尽可能大地实现open和close这两个操作的封装。最理想的情况是,我们在主业务逻辑的代码中,完全不需要显式地调用open和close这两个方法。context manager就能帮助我们达到这一目的。请看下面的定义。
class MyContextManager:
def __init__(self):
self.conn = MyFakeConnection()
def __enter__(self):
self.conn.open()
return self.conn
def __exit__(self, *exc):
self.conn.close()
我们把open操作放在__enter__方法中,而close操作放在__exit__方法中。注意__enter__方法的返回值是一个MyFakeConnection对象。它是怎么返回给调用者的呢?请看下面的代码。
with MyContextManager() as conn:
conn.request()
上面的代码使用as关键字来接收__enter__方法的返回值。代码的输出如下。
Connection opened
A request sent
Connection closed