Python深入学习之上下文管理器

1295次阅读  |  发布于5年以前

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

关闭文件

我们会进行这样的操作:打开文件,读写,关闭文件。程序员经常会忘记关闭文件。上下文管理器可以在不需要文件的时候,自动关闭文件。

下面我们看一下两段程序:

复制代码 代码如下:

without context manager

f = open("new.txt", "w")
print(f.closed) # whether the file is open
f.write("Hello World!")
f.close()
print(f.closed)

以及:

复制代码 代码如下:

with context manager

with open("new.txt", "w") as f:
print(f.closed)
f.write("Hello World!")
print(f.closed)

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

上面的上下文管理器基于f对象的exit()特殊方法(还记得我们如何利用特殊方法来实现各种语法?参看特殊方法与多范式)。当我们使用上下文管理器的语法时,我们实际上要求Python在进入程序块之前调用对象的enter()方法,在结束程序块的时候调用exit()方法。对于文件对象f来说,它定义了enter()和exit()方法(可以通过dir(f)看到)。在f的exit()方法中,有self.close()语句。所以在使用上下文管理器时,我们就不用明文关闭f文件了。

自定义

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

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

复制代码 代码如下:

customized object

class VOW(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 suffix

with VOW("I'm fine") as myvow:
print(myvow.text)

print(myvow.text)

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8