首页 > 代码库 > python深入学习02 上下文管理器

python深入学习02 上下文管理器

上下文管理器(context manager)主要用于规定某个对象的使用范围。一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存)。它的语法形式是with...as...

 

关闭文件


 上下文管理器有个特别好的优点:可以在不使用文件的时候,自动关闭文件,节省了f.close()的步骤

 

上下文管理器有隶属于它的程序块。当隶属的程序块执行结束的时候(也就是不再缩进),上下文管理器自动关闭了文件 (我们通过f.closed来查询文件是否关闭)。我们相当于使用缩进规定了文件对象f的使用范围

 

上面的上下文管理器基于f对象的__exit__()特殊方法。当我们使用上下文管理器的语法时,我们实际上要求Python在进入程序块之前调用对象的__enter__()方法,在结束程序块的时候调用__exit__()方法。对于文件对象f来说,它定义了__enter__()和__exit__()方法(可以通过dir(f)看到)。

本质点,在f的__exit__()方法中,有self.close()语句。所以在使用上下文管理器时,我们就不用明文关闭f文件了。

 

 

自定义


 任何定义了__enter__()和__exit__()方法的对象都可以用于上下文管理器。文件对象f是内置对象,所以f自动带有这两个特殊方法,不需要自定义。

下面,我们自定义用于上下文管理器的对象,就是下面的myTest:

 

#!/usr/bin/env pythonclass SayTest(object):    def __init__(self, text):        self.text = text    def __enter__(self):        self.text = "I say: " + self.text    # add prefix        return self                          # note: return an object    def __exit__(self,exc_type,exc_value,traceback):        self.text = self.text + "!"          # add suffixwith SayTest("I‘m fine") as myTest:    print(myTest.text)print(myTest.text)

 

 

 输出结果:

I say: Im fineI say: Im fine!

我们可以看到,在进入上下文和离开上下文时,对象的text属性发生了改变(最初的text属性是"I‘m fine")。

__enter__()返回一个对象。上下文管理器会使用这一对象作为as所指的变量,也就是myTest。

注意: __exit__()中有四个参数。当程序块中出现异常(exception),__exit__()的参数中exc_type, exc_value, traceback用于描述异常。我们可以根据这三个参数进行相应的处理。如果正常运行结束,这三个参数都是None。在我们的程序中,我们并没有用到这一特性。