python上下文管理器

背景知识:

    对于系统的资源,例如文件,数据库连接,socket等而言,应用程序打开这些资源使用,使用完成后必须要做的一件事情就是关闭或者断开连接。因为操作系统分配给我们的资源连接都是有上限的,长时间不关闭有可能会抛出异常。

    例如:

            文件资源长期不关闭,有可能会出现‘Too nany open files’的错误。

            数据库长期不关闭,有可能会出现‘Can not connect Mysql Server Too many connections’的错误

来看看如何关闭文件资源:

普通版:

def m1():
    f = open('output.txt', 'w')
    # 如果write的过程中出现了错误,程序没有办法close
    f.write('张飞龙')
    f.close()

改良版:

def m2():
    f = open('output.txt', 'w')
    # 使用try
    try:
        f.write('张飞龙')
    except IOError:
        print('oops error')
    finally:
        f.close()

高级版

def m3():
    with open('output.txt', 'r') as f:
        f.write('张飞龙')

open的方法返回值赋值给变量f,当离开with代码块的时候,系统会自动调用f.close()方法,那么他的实现原理是什么?在讲with的原理前要涉及到另外一个概念,就是上下文管理器(context manager)

概念:

    实现了上下文协议的对象即为上下文管理器。

上下文协议:__enter__,__exit__

作用:用于资源的获取和释放。

使用上下文管理器:

class File():
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode

    def __enter__(self):
        '__enter__方法返回资源对象'
        print('begin entering')
        self.f = open(self.filename, self.mode)

        return self.f

    def __exit__(self, *args):
        '''__exit__方法处理一些清理工作'''
        print('will exit')
        self.f.close()

# 因为File类实现了上下文管理器,所以现在就可以使用with语句了
with File('output.txt', 'w') as f:
    print('writing')
    f.write('hello,张飞龙')

begin entering
writing
will exit

使用contextmanager装饰器实现:

from contextlib import contextmanager


@contextmanager
def my_open(path, mode):
    f = open(path, mode)
    yield f
    f.close()

with my_open('output.txt', 'w') as f:
    f.write('hello, the simplest context manager')

总结:

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















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值