上下文管理器是一个包装任意代码块的对象。上下文管理器保证进入上下文管理器时,每次代码执行的一致性;当退出上下文管理器时,相关资源会被正确回收(这里被正确回收指的是在__exit__方法自定义回收代码,比如关闭数据库游标)。
值得注意的是,上下文管理器一定能够保证退出步骤的执行。如果进入上下文管理器,根据定义,一定会有退出步骤。即使内部的代码抛出异常,这点也成立。事实上,如果退出步骤处理合适,那么上下文管理器的退出代码为处理这类异常提供一个机会(虽然不强制要求一定要处理异常)。
上下文管理器用得最多的就是作为确保资源被正确清理的一种方式。
上下文管理器要求对象必须定义一个__enter__方法和一个__exit__方法,且后者必须接受特定参数,前者除了self参数不接受任何其他参数。其中enter方法返回的值被赋给as后面的变量,exit方法如果返回true,那么如果包装的代码块执行出现异常,解释器是不会抛出异常的。
class ContextManager(object):
def __int__(self):
self.entered = False
def __enter__(self):
self.entered = True
return self
def __exit__(self, exc_type, exc_val, exc_tb): # 参数分别为异常类型,异常实例,异常回溯
self.entered = False
if exc_val:
print exc_val
return True
with ContextManager() as cm:
print cm.entered # True
print cm.entered # False
要注意的是上下文管理器执行完之后解释器并不会回收代码块内的对象内存