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

2018-10-3110:03:57编程语言入门到精通Comments1,860 views字数 1770阅读模式

with 语句是 Pyhton 上的一种简化语法,with 语句是从 Python 2.5 开始引入的一种与异常处理相关的功能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必需的“清理”操作,释放资源。比如文件使用后自动关闭、数据库的打开和自动关闭等。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

语法格式是这样的:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

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

通过 with 语句在编写代码时,会使代码变得更加简洁。在编写代码时,不用再显示的去关闭文件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

语句的执行过程:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

  1. 在执行 with 语句时,首先执行 with 后面的 open 代码
  2. 执行完代码后,会将代码的结果通过 as 保存到 f 中
  3. 然后在下面实现真正要执行的操作
  4. 在操作后面,并不需要写文件的关闭操作,文件会在使用完后自动关闭

实际上,在文件操作时,并不是不需要写文件的关闭,而是文件的关闭操作在 with 的上下文管理器中的协议方法里已经写好了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

当文件操作执行完成后, with语句会自动调用上下文管理器里的关闭语句来关闭文件资源。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

with 语句在执行时,需要调用上下文管理器中的 __enter__ 和 __exit__ 两个方法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

__enter__ 方法会在执行 with 后面的语句时执行,一般用来处理操作前的内容。比如一些创建对象,初始化等。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

__exit__ 方法会在 with 内的代码执行完毕后执行,一般用来处理一些善后收尾工作,比如文件的关闭,数据库的关闭等。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

在自定义上下文管理器时,只需要在类中实现 __enter__ 和 __exit__ 两个方法即可。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

模拟文件打开过程:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

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')
复制代码

程序执行结果:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

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

__exit__ 方法中有三个参数,用来接收处理异常,如果代码在运行时发生异常,异常会被保存到这里。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

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

异常信息的处理文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

当with中执行的语句发生异常时,异常信息会被发送到 __exit__ 方法的参数中,这时可以根据情况选择如何处理异常。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

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__函数执行异常处理时,会根据函数的返回值决定是否将系统抛出的异常继续向外抛出。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

如果返回值为 False 就会向外抛出,用户就会看到。 如果返回值为 True 不会向外抛出,可以将异常显示为更加友好的提示信息。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

作者:贾富程
来源:掘金文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/7590.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/ymba/7590.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定