Pyhton编程提高:with上下文管理器

2023年 7月 14日 71.8k 0

with 语句是 Pyhton 上的一种简化语法,with 语句是从 Python 2.5 开始引入的一种与异常处理相关的功能。

with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必需的“清理”操作,释放资源。比如文件使用后自动关闭、数据库的打开和自动关闭等。

语法格式是这样的:

with open('test', 'w') as f:
    f.write('Python大法好')复制代码

通过 with 语句在编写代码时,会使代码变得更加简洁。在编写代码时,不用再显示的去关闭文件。

语句的执行过程:

  • 在执行 with 语句时,首先执行 with 后面的 open 代码
  • 执行完代码后,会将代码的结果通过 as 保存到 f 中
  • 然后在下面实现真正要执行的操作
  • 在操作后面,并不需要写文件的关闭操作,文件会在使用完后自动关闭
  • 实际上,在文件操作时,并不是不需要写文件的关闭,而是文件的关闭操作在 with 的上下文管理器中的协议方法里已经写好了。

    当文件操作执行完成后, with语句会自动调用上下文管理器里的关闭语句来关闭文件资源。

    with 语句在执行时,需要调用上下文管理器中的 __enter__ 和 __exit__ 两个方法。

    __enter__ 方法会在执行 with 后面的语句时执行,一般用来处理操作前的内容。比如一些创建对象,初始化等。

    __exit__ 方法会在 with 内的代码执行完毕后执行,一般用来处理一些善后收尾工作,比如文件的关闭,数据库的关闭等。

    在自定义上下文管理器时,只需要在类中实现 __enter__ 和 __exit__ 两个方法即可。

    模拟文件打开过程:

    import time
    
    
    class MyOpen(object):
        def __init__(self,file, mode):
            self.__file = file
            self.__mode = mode
    
        def __enter__(self):
            print('__enter__ run ... 打开文件')
            self.__handle = open(self.__file, self.__mode)
            return self.__handle
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('__exit__... run ... 关闭文件')
            self.__handle.close()
    
    
    with MyOpen('test','w') as f:
        f.write('Python 大法好')
        time.sleep(3)
    
    print('over')
    复制代码

    程序执行结果:

    __enter__ run ... 打开文件
    __exit__ run ... 关闭文件
    over
    复制代码

    __exit__ 方法中有三个参数,用来接收处理异常,如果代码在运行时发生异常,异常会被保存到这里。

    • exc_type : 异常类型
    • exc_val : 异常值
    • exc_tb : 异常回溯追踪

    异常信息的处理

    当with中执行的语句发生异常时,异常信息会被发送到 __exit__ 方法的参数中,这时可以根据情况选择如何处理异常。

    class MyCount(object):
        def __init__(self, x, y):
            self.__x = x
            self.__y = y
    
        def __enter__(self):
            return self
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            # 通过 参数接收到的值,来判断程序执行是否出现异常
            # 如果是 None ,说明没有异常
            if exc_type == None:
                print('计算正确执行')
            else:
                # 否则出现异常,可以选择怎么处理异常
                print(exc_type,exc_val)
            # 返回值决定了捕获的异常是否继续向外抛出
            # 如果是 False 那么就会继续向外抛出,程序会看到系统提示的异常信息
            # 如果是 True 不会向外抛出,程序看不到系统提示信息,只能看到else中的输出
            return True
    
        def div(self):
            print(self.__x / self.__y)
    
    
    with MyCount(6, 0) as mc:
        mc.div()
    复制代码

    在 __exit__函数执行异常处理时,会根据函数的返回值决定是否将系统抛出的异常继续向外抛出。

    如果返回值为 False 就会向外抛出,用户就会看到。 如果返回值为 True 不会向外抛出,可以将异常显示为更加友好的提示信息。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论