详解python中的with关键字

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

如何正确的关闭一个文件呢?

1.普通版

def test0():
    f = open("1.txt", "w")
    f.write("0000")
    f.close()

2.进阶版

def test1():
    f = open("1.txt", "w")
    try:
        f.write("111111")
    except Exception:
        print("ERROR")
    finally:
        f.close()

3.高级版

def test2():
    with open("1.txt", "w") as f:
        f.write("2222")
使用with关键字的方法更为简洁,它的实现原理是什么,这就涉及到上下文管理器。

任何实现了 __enter__()__exit__() 方法的对象都可称之为上下文管理器

4.用类还原with的实现原理

class Test4(object):
    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()
with Test4("1.txt", "w") as f:
    f.write("4444")
"""
首先Test4("1.txt", "w")初始化实例对象,
然后with会寻找类中是否有__enter__  和 __exit__,
如果有则调用__enter__函数,
最后__enter__() 方法返回资源对象,这里就是你将要打开
的那个文件对象,__exit__() 方法处理一些清除工作。
"""

5.使用contextmanager装饰器,实现with功能

from contextlib import contextmanager
"""
Python 还提供了一个 contextmanager 的装饰器,更进一步简化
了上下文管理器的实现方式。通过 yield 将函数分割成两部分,yield 之前的
语句在 __enter__ 方法中执行,yield 之后的语句在 __exit__ 方法中执行。
紧跟在 yield 后面的值是函数的返回值。
"""
@contextmanager
def test5(path, mode):
    f = open(path, mode)
    yield f
    f.close()
with test5('out.txt', 'w') as f:
    f.write("5555")
总结:

Python 提供了 with 语法用于简化资源操作的后续清除操作,是 try/finally 的替代方法,实现原理建立在上下文管理器之上。此外,Python 还提供了一个 contextmanager 装饰器,更进一步简化上下管理器的实现方式。

你可能感兴趣的:(学习笔记,python,with,上下文管理器)