[python笔记] with语句和上下文管理

    python中读写文件的语句是相当少的,代码如下:

# 创建文件
f = open('output.txt', 'w')
# 写入内容进文件
f.write('python')
# 关闭文件
f.close()

    但是,这还是不够简洁,有可能会忘记写关闭文件的语句f.close(),python执行写入文件的操作是惰性的,因为读写文件都是io操作,所以执行任务处于较低的优先级,当前没有其他任务就会执行写入,要是有其他任务,写入文件就会一直等待;

    所以就有了with语句,代码如下:

with open('output.txt', 'w') as f:
        f.write('python')

    with语句会自动处理上下文,自动关闭文件,那么底层是怎么实现的呢,主要是依赖于__enter__(管理上文),__exit__(管理下文)方法,代码如下:

# 面向对象实现上下文管理
class File(object):
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode

    def __enter__(self):
        print('entering')
        self.f = open(self.filename, self.mode)
        return self.f

    def __exit__(self, *args):
        print('exit')
        self.f.close()

with File('input.txt', 'w') as f:
    f.write('i love you')

结果:

entering
exit

    从代码上来看,__enter__方法就是负责一段业务的环境准备(打开文件),with语句里就执行你要撰写的业务,__exit__方法就负责业务的收尾工作(关闭文件),所以只要是实现了这两个方法的类,就可以用with语句管理上下文。

    python也提供了一个模块contextlib,来处理上下文,代码如下:

from contextlib import contextmanager


# 通过 yield 将函数分割成两部分,
# yield 之前的语句在 __enter__ 方法中执行,
# yield 之后的语句在 __exit__ 方法中执行。
# 紧跟在 yield 后面的值是函数的返回值;
@contextmanager
def my_open(path, mode):
    f = open(path, mode)
    yield f
    f.close()

with my_open('input.txt', 'r') as f:
    content = f.read()
    print(content)
# 结果
i love you

    contextmanager就是一个装饰器,配合yield语句,可以将函数里面的业务分割成上文,yield之前的语句是在__enter__方法中执行,yield后面的值是函数的返回值,yield之后的语句在__exit__方法中执行;

总结:

    with语句和上下文管理,__enter__方法和__exit__方法就是一种协议,满足这个协议,就可以用with语句访问,并管理上下文;



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值