• 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
  • 相关阅读:
    Spring Cloud之微服务
    树莓派4b linux内核调试(jtag、kgdb)
    SQL Server 2022新功能概览
    Springboot中开启多线程,实现异步非阻塞、异步阻塞、有无返回值的场景
    7.features特征
    Linux学习-56-dmesg、free、wc、xargs 命令
    linux常用命令之设定acl相关命令 setfacl/getfacl/chattr
    The given SOAPAction http__xxxxx_xx does not match an operation
    Keycloak之Gerrit安装与集成-yellowcong
    外汇天眼:Poipex 申请出金超过100天不到账!投资者250万入金打水漂!所有联系方式全不回应
  • 原文地址:https://blog.csdn.net/m0_56945138/article/details/124898070