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()的区别

下一讲:

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

时间: 2024-10-09 12:55:49

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

python2.7高级编程 笔记一(Python中的with语句与上下文管理器学习总结)

0.关于上下文管理器上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象. with manager as var: do_something(var) 相当于以下情况的简化: var = manager.__enter__() try: do_something(var) finally: manager.__exit__() 换言之,PEP 343中定义的上下文管理器协议允许将无聊的try...except...finally结构抽象到一个单独的类中,仅

Python高级语法-私有属性-with上下文管理器(4.7.3)

目录 1.说明 2.代码 关于作者 @ 1.说明 上下文管理器 这里使用with open操作文件,让文件对象实现了自动释放资源.我们也能自定义上下文管理器,通过__enter__()和__exit__()这两个魔术方法来自定义的操作文件 当有上下文使用的场景的时候,如打开一个东西要关闭,像等文件等资源,就可以使用这种方式去定义一个上下文管理器 2.代码 class File(): def __init__(self,filename,mode): self.filename = filenam

Python菜鸟晋级06----特殊属性整理

Python一切皆对象(object),每个对象都可能有多个属性(attribute). #现在我们来总结下所有的系统定义属性和方法, 先来看下保留属性: >>> Class1.__doc__ # 类型帮助信息 'Class1 Doc.' >>> Class1.__name__ # 类型名称 'Class1' >>> Class1.__module__ # 类型所在模块 '__main__' >>> Class1.__bases__

上下文管理器学习与简单的文件复制

# =====================上下文管理器======================================== ''' 既然文件一定要及时关闭,是否能够让Python自动执行这个关闭过程,上下文管理器可以完成自动关闭文件. 能否同时管理多个文件的自动关闭 ''' with open (r"D:\s14\day1\test_doc.py","r+") as file: #代表用上下文管理器打开一个文件 file.write("pr

Python:contextlib模块——上下文管理器工具

上篇博文简单的讲了下with语句的用法以及上下文管理器对象的概念,想必对上下文管理器对象有一定的了解.一个对象如果实现了上下文管理协议,也就是在类中定义了__enter__()和__exit__()方法两个方法的对象,都可以称为上下文管理器对象. 但是,Python中有个contextlib模块,是个比with优美的东西,提供上下文机制的,它是通过Generator装饰器实现的,不再是采用__enter__和__exit__. contextlib模块对外有三个接口,分别是contextlib.

谈一谈Python的上下文管理器

经常在Python代码中看到with语句,仔细分析下,会发现这个with语句功能好强,可以自动关闭资源.这个在Python中叫上下文管理器Context Manager.那我们要怎么用它,什么时候用它呢.这里我们就来聊一聊. 上下文管理器的作用 很多情况,当我们使用完一个资源后,我们需要手动的关闭掉它,比如操作文件,建立数据库连接等.但是,在使用资源的过程中,如果遇到异常,很可能错误被直接抛出,导致来不及关闭资源.所以在大部分程序语言里,我们使用"try-finally"语句来确保资源

Python菜鸟晋级03----repr() 与str() 函数的区别

两者均是将数值转换成字符串的形式,但是有细微的区别 str()会创建一个适合人阅读的字符串. repr()会创建适合解释器阅读的字符串. >>> hello = 'hello, world\n' >>> hellos = repr(hello) >>> hellos "'hello, world\\n'" #出现反斜杠进行转意 >>> hellos=str(hello) >>> hellos 'h

Python 上下文管理器和else块

最终,上下文管理器可能几乎与子程序(subroutine)本身一样重要.目前,我们只了解了上下文管理器的皮毛--Basic 语言有with 语句,而且很多语言都有.但是,在各种语言中 with 语句的作用不同,而且做的都是简单的事,虽然可以避免不断使用点号查找属性,但是不会做事前准备和事后清理.不要觉得名字一样,就意味着作用也一样.with 语句是非常了不起的特性.  --Raymond Hettinger 雄辩的 Python 布道者 先做这个,再做那个:if语句之外的else块 这个语言特性

python上下文管理器及with语句

with语句支持在一个叫上下文管理器的对象的控制下执行一系列语句,语法大概如下: with context as var: statements 其中的context必须是个上下文管理器,它实现了两个方法__enter__,__exit__. 1.需求是怎么产生的 在正常的管理各种系统资源(文件.锁定和连接),在涉及到异常时通常是个棘手的问题.异常很可能导致控制流跳过负责释放关键资源的语句. 看一段简单的文件写入代码: filename = 'my_file.txt' f = open(file