首页 > 代码库 > Python菜鸟晋级05----with....as....(上下文管理器)

Python菜鸟晋级05----with....as....(上下文管理器)

介绍

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

应用

比较一下两段代码:

没有使用上下文管理器:

writer = open("test.txt", "w")
try:
    writer.write('Hello ')
    writer.write('World')
finally:
    writer.close()

使用上下文管理器:

with open("test.txt", "w") as writer: 
    writer.write("Hello World!")
上面两段代码作用相同,但是下面的代码是不是比上面的代码优雅多了?


       open函数既能够当做一个简单的函数使用,又能够作为上下文管理器。这是因为open函数返回了一个文件类型变量,而这个文件类型实现了我们之前用到的write方法,但是想要作为上下文管理器还必须实现一些特殊的方法,我会在接下来的小节中介绍。

自定义上下文管理器

要实现上下文管理器,必须实现两个方法——一个负责进入语句块的准备操作(__enter__ 方法),另一个负责离开语句块的善后操作(__exit__ 方法

当一个对象被用作上下文管理器时:
__enter__ 方法将在进入代码块前被调用。
__exit__ 方法则在离开代码块之后被调用(即使在代码块中遇到了异常)。

class Test:
   def __enter__(self):
        print("进入模块")
   def __exit__(self,*unused):
        print("离开模块")
with Test():                             #由于我不需要调用方法,因此我没有使用as关键词
    print("模块中执行的语句")
        

输出结果

>>> 
进入模块
模块中执行的语句
离开模块
>>>

自己实现的上下文管理器

class PypixOpen:
 
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode
 
    def __enter__(self):
        self.openedFile = open(self.filename, self.mode)
        return self.openedFile
 
    def __exit__(self, *unused):
        self.openedFile.close()
 
with PypixOpen(filename, mode) as writer:
    writer.write("Hello World from our new Context Manager!")

值得注意的是:

        我们完全忽视了语句块内部可能出现的问题。
        如果语句块内部发生了异常,__exit__方法将被调用,而异常将会被重新抛出(re-raised)。当处理文件写入操作时,大部分时间你肯定不希望隐藏这些异常,所以这是可以的。而对于不希望重新抛出的异常,我们可以让__exit__方法简单的返回True来忽略语句块中发生的所有异常(大部分情况下这都不是明智之举)。
         上面代码*unused 指向exc_type, exc_value, traceback三个参数,当程序块中出现异常(exception),这三个参数用于描述异常。我们可以根据这三个参数进行相应的处理。如果正常运行结束,这三个参数都是None。


上一讲:Python菜鸟晋级04----raw_input() 与 input()的区别

下一讲:

如果有什么疑问欢迎到我的微信公众号提问~
技术分享

Python菜鸟晋级05----with....as....(上下文管理器)