• with和上下文管理器


    with和上下文管理器

    如果你有时间阅读源码的习惯,可能会看到一些优秀的代码会出现带有with关键字的语句。

    对于系统资源如文件,数据库连接,socket而言,应用程序打开这些资源并执行完业务逻辑之后,必须要做的事情就是关闭该资源。

    在上篇文件中,我们读写文件操作,完毕之后,关闭文件对象。调用close方法,下面来看看如何正确的关闭一个文件。

    普通版
    def func():
        f = open("1.txt", "w")
        f.write("Python")
        f.close()
    

    这样写有一个误区,如果在调用write方法时,出现了异常无法继续执行下面代码,资源就被该程序一直占用系统资源。

    进阶版
    def func():
        f = open("1.txt", "w")
        try:
            f.write("python")
        except IOError:
            print("oops, error")
        finally:
            f.close()
    

    上面的程序我们使用异常进行了捕获,finally内代码执行关闭资源。如果需要学习异常的使用,请看下篇文章。

    高级版
    def func():
        with open("1.txt", "r") as f:
            f.write("python")
    

    简洁优雅的写法就是使用with关键字。with的作用和使用异常捕获try/finally语句是一样的。想了解with原理,我们必须知道上下文管理器。

    上下文管理器

    任何实现了__enter__()__exit__()方法的对象都可以称为上下文管理器,上下文管理器对象可以使用with关键字,文件对象也实现了上下文管理器。

    自定义类实现上下文管理器,示例代码:

    class File():
        def __init__(self, file_name, mode):
            self.file_name = file_name
            self.mode = mode
        
        def __enter__(self):
            self.f = open(self.file_name, self.mode)
            return self.f
        
        def __exit__(self, *args):
            self.f.close()
    

    enter()方法返回资源对象,这就是要打开的文件对象,exit()方法处理清除工作。因为File类实现了上下文管理器,现在就可以使用with语句了。

    with File("1.txt", "w") as f:
        f.write("hello, python")
    

    这样一来,系统自动调用close方法实现关闭资源。

    装饰器实现上下文管理器

    Python提供了contextmanager的装饰器,更进一步简化了上下文管理器的实现方式,通过yield将函数分为两部分,yield之前的语句在__enter__()方法中执行,yield之后的语句在__exit__()执行。

    from contextlib import contextmanger
    
    @contextmanger
    def my_open(path, mode):
        f = open(path, mode)
        yield f
        f.close()
    

    调用:

    with my_open("1.txt", "w") as f:
        f.write("hello, python")
    

    本文中应用到了装饰器,异常,前面未讲到,如有需要,请看以后的文章,后续文章会讲到装饰器,下篇文章则是异常的使用。

  • 相关阅读:
    I'm Telling the Truth
    B-shaass and lights codeForces
    1
    不容易系列之(4)——考新郎 HDU
    犯人冲突
    不互质的和
    OI回忆录
    NOI2018退役记
    uoj221【NOI2016】循环之美
    uoj220【NOI2016】网格
  • 原文地址:https://www.cnblogs.com/liudemeng/p/12297780.html
Copyright © 2020-2023  润新知