文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python编程ContextManager上下文管理器讲解

2024-04-02 19:55

关注

什么是上下文管理器

官方解释

上下文管理器是一个对象它定义了在执行 with 语句时要建立的运行时上下文上下文管理器处理进入和退出所需的运行时上下文以执行代码块上下文管理器通常使用 with 语句调用,但也可以通过直接调用它们的实例方法来使用

一顿花里胡哨猛如虎,结果我也不太懂

简单一句话

同时包含 __enter__() 和 __exit__() 方法的对象就是上下文管理器

__enter__(self)

进入上下文管理器自动调用的方法

该方法会在 with ... as ... 代码块执行之前执行

如果 with 语句有 as 子句,且该方法有返回值,那么该方法的返回值会被赋值给 as 子句后的变量,最常见的 with open('file_path', 'w') as file: 

该方法可以返回多个值,因此在 as 子句后面也可以指定多个变量(多个变量必须由“()”括起来组成元组)

__exit__(self, exc_type, exc_value, exc_traceback)

退出上下文管理器自动调用的方法,会返回一个布尔类型的值

该方法会在 with ... as ... 代码块执行之后执行

如果 with ... as ... 代码块成功执行结束,程序自动调用该方法,且三个参数都为 None

如果 with ... as ... 代码块执行时发生异常,通过 sys.exc_info() 得到异常信息,三个参数值分别是:异常类型、异常信息、异常回溯信息类型

有哪些常见上下文管理器?

打开文件


with open('file_path', 'w') as file:
    file.write('hello world !')

拆分了解

上下文表达式: with open('file_path', 'w') as file: 

上下文管理器: open('file_path', 'w') 

file:可以理解为资源对象

执行顺序

先执行 open() 的 __enter__() 方法,将返回值赋值给 file

执行 file.write('hello world !') 

最后执行 open() 的 __exit__() 方法

自定义上下文管理器

其实有两种方式

基于类实现上下文管理器

只需要给对象添加一个 __enter__ 和一个 __exit__ 方法


import sys
class Resource:
    def __init__(self, name):
        self.name = name
        print("== 初始化方法 ==")
 
    def __enter__(self):
        print(f"** 进入上下文管理器自动调用:name is {self.name}")
        # 可以返回任意类型的值
        return {"name": self.name}
 
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"## 退出上下文管理器自动调用:", sys.exc_info(), exc_type, exc_val, exc_tb)
        if exc_tb is None:
            print("没有异常时关闭资源")
        else:
            print("遇到异常时关闭资源")

通过 with 来调用该上下文管理器

也称为:使用 with ... as ... 管理资源


with Resource("小菠萝") as r:
    print(r)

console 输出结果

== 初始化方法 ==
** 进入上下文管理器自动调用:name is 小菠萝
{'name': '小菠萝'}
## 退出上下文管理器自动调用: (None, None, None) None None None
没有异常时关闭资源

__exit__() 方法的三个参数值都是 None

with 代码块抛出异常


with Resource("异常小菠萝") as r:
    print('[with代码块] 异常之前的代码')
    raise Exception("抛出了 Exception")
    print('[with代码块] ~~~~~~~~异常之后的代码')

console 输出结果

== 初始化方法 ==
** 进入上下文管理器自动调用:name is 异常小菠萝
[with代码块] 异常之前的代码
## 退出上下文管理器自动调用: (<class 'Exception'>, Exception('抛出了 Exception'), <traceback object at 0x10e203200>) <class 'Exception'> 抛出了 Exception <traceback object at 0x10e203200>
遇到异常时关闭资源
Traceback (most recent call last):
  File "/Users/polo/Documents/pylearn/第七章:文件相关/1_上下文管理器.py", line 36, in <module>
    raise Exception("抛出了 Exception")
Exception: 抛出了 Exception

代码块抛出异常的时候,可以看到 __exit__() 方法的三个参数值的确来源于 sys.exc_info() 

总结

__exit__() 返回 True


    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"## 退出上下文管理器自动调用:", sys.exc_info(), exc_type, exc_val, exc_tb)
        if exc_tb is None:
            print("没有异常时关闭资源")
        else:
            print("遇到异常时关闭资源")
            return True
 
 
# 再次运行
with Resource("异常小菠萝") as r:
    print('[with代码块] 抛出异常之前的代码')
    raise Exception
    print('[with代码块] 抛出异常之后的代码')

console 输出结果

== 初始化方法 ==
** 进入上下文管理器自动调用:name is 异常小菠萝
[with代码块] 异常之前的代码
## 退出上下文管理器自动调用: (<class 'Exception'>, Exception('抛出了 Exception'), <traceback object at 0x100e29200>) <class 'Exception'> 抛出了 Exception <traceback object at 0x100e29200>
遇到异常时关闭资源

不再抛出异常

基于生成器实现上下文管理器

通过装饰器 contextlib.contextmanager,来定义自己所需的基于生成器的上下文管理器


from contextlib import contextmanager 
@contextmanager
def file_manager(name, mode):
    try:
        # 1、打开文件
        file = open(name, mode)
        # 2、返回文件资源对象
        yield file
    finally:
        # 3、关闭文件
        file.close() 
with file_manager('a.txt', 'w') as file:
    print(file)
    file.write('hello world')

函数 file_manager() 就是一个生成器

当执行 with as 语句时,获取文件资源对象,生成器暂停执行,返回文件资源对象并赋值给 file

当 with 语句执行完后,生成器继续执行剩余代码,关闭文件,释放资源

总结

 with 语句的教程

https://www.jb51.net/article/172132.htm

以上就是Python编程ContextManager上下文管理器讲解的详细内容,更多关于Python编程Context Manager的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯