• python上下文管理器


    1. 前言

    偶然间认识了with,但它是什么意思,有什么用?
    
    对于这些很是模糊,下面我们就细细看来。
    
    • 1
    • 2
    • 3

    2. 先谈 ‘with’

    1. 刚学习文件操作时的做法

    这是初学时最基础的方法,打开文件,读(写)内容,关闭文件。

    # 1.打开文件
    file = open("D:\\record.txt","r",encoding='utf-8')  # 打开的文件区分大小写
    # 2.读取文件的内容
    text = file.read()
    print(text)
    # 3.关闭文件
    file.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 有个小问题

    打个比方:我在打开文件后,要进行读(写)的操作,刚好在这个过程中出现了异常 导致后面的代码不能继续执行,也就是说文件无法关闭(文件资源无法释放)。

    我想到了,之前学习过try

    file = open("D:\\record.txt","r",encoding='utf-8')
    try:
        f = file.read()
    finally:
        file.close()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意: 无论是否发生异常,它都会去执行finally 关闭文件。

    1. 针对问题2做的升级

    with会自动调用close()

    with open('a.txt') as f:
        x = f.read()
    
    • 1
    • 2

    3. 上下文管理器

    一个类只要实现  __enter__ 和 __exit__ 方法都可称之为上下文管理器。
    
    __enter__:with执行前调用,returnopen的文件对象
    __exit__ :with执行完被调用
    
    • 1
    • 2
    • 3
    • 4

    步骤:

    1. 首先会调用__init__方法
    2. 调用__enter__方法,return返回要打开的对象,它会通过as赋值给变量f
    3. 执行with里面的语句
    4. 最后执行__exit__方法
    class File():
        def __init__(self, name, mode):
            print('第1 __init__')
            self.name = name  # 文件路径
            self.mode = mode  # 打开方式
    
        def __enter__(self):
            print('第2 __enter__')
            self.file = open(self.name, self.mode)
            return self.file
    
        # def __exit__(self, *args):
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('第5 __exit__')
            self.file.close()
    
    
    with File('a.txt', 'r') as f:
        print('第3 with')
        print('第4', f.read())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    打印结果:
    
    第1 __init__
    第2 __enter__
    第3 with4 1231231235 __exit__
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5. 装饰器contextmanager

    contextmanager使得上下文管理器更加简单。

    from contextlib import contextmanager
    
    
    @contextmanager
    def fun_test(path, mode):
        print('1')
        file = open(path, mode)
        print('2')
        yield file
        print('3')
        file.close()
    
    
    with fun_test('a.txt', 'r') as f:
        print('4')
        print(f.read())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    r需要我们自己进行异常处理,如下代码添加try-finally

    from contextlib import contextmanager
    
    
    @contextmanager
    def fun_test(path, mode):
        try:
            print('1')
            file = open(path, mode)
            print('2')
            yield file
            print('3')
        finally:
            file.close()
    
    
    with fun_test('a.txt', 'r') as f:
        print('4')
        print(f.read())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1
    2
    4
    123123123
    3
    
    1. 调用 fun_test方法,开始从函数上面向下执行
    2. 执行yield  返回file,它的返回值给了f
    3. 执行with语句
    4.yield后面继续执行
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    音视频的Buffer处理
    1.2 无监督学习和强化学习
    【计算机网络】互联网公司的网络架构和业务场景
    OA项目之我的会议(会议排座&送审)
    Linux shell编程学习笔记14:编写和运行第一个shell脚本hello world!
    类与对象--末篇(c++)
    win11识别不到外置机械硬盘
    飞书项目发布3个月,已签约理想汽车、安克创新等100余家公司
    吃瓜教程2|线性模型
    About 10.30 This Week
  • 原文地址:https://blog.csdn.net/m0_56945138/article/details/124898070