上下文管理器(contextor)

 

上下文管理器

说明:

上下文管理器和迭代器很相似,实现了迭代协议函数的对象即为迭代器,实现了上下文协议函数对象即为上下文管理器。迭代器实现了__iter__和__next__方法。而上下文管理器则是__enter__和__exit__方法。

 

class Contexto(object):
    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

contexto=Contexto()

说明:

Contexto实现了__enter____exit__上下管理器协议,当实例化对象的时候则创建了上下文管理器contexto

class Contexto(object):
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

contexto=Contexto()

with contexto as var :
    print(var)

说明:

配合with语句的时候,上下文管理器会自动调用__enter__,然后进入上下文运行时环境,如果有as语句,返回自身或另一个与运行时上下文相关的对象,值赋值给var。当后面的语句执行完毕,或者发生异常,就会进入__exit__方法内,并且会把对于异常的参数传过来,如果__exit__方法返回的是True,则with语句块不会显示抛出异常,终止程序,如果返回None或者False,异常会被主动raise,并终止程序。

为什么要用上下文管理器?

  1. 可以以一种更加优雅的方式,操作(创建/获取/释放)资源,如文件操作、数据库连接;
  2. 可以以一种更加优雅的方式,处理异常;

说明:

处理异常,通常都是使用 try...execept.. 来捕获处理的。这样做一个不好的地方是,在代码的主逻辑里,会有大量的异常处理代理,这会很大的影响我们的可读性。 

class Contexto(object):
    def __enter__(self):
        print()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        return  True


    def opens(self):
        a=1+''
        print(a)

contexto=Contexto()

with contexto as var :
    var.opens()

说明:

异常可以在__exit__ 进行捕获并由你自己决定如何处理,是抛出呢还是在这里就解决了。在__exit__ 里返回 True(没有return 就默认为 return False),就相当于告诉 Python解释器,这个异常我们已经捕获了,不需要再往外抛了。

在 写__exit__ 函数时,需要注意的事,它必须要有这三个参数:

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

当主逻辑代码没有报异常时,这三个参数将都为None。

 

上下管理器工具

import contextlib
@contextlib.contextmanager
def contexts(file_name):
    print('首先进入我__enter__')
    file_one=open(file_name,'r')
    yield file_one                #yield 之前为__enter__   yield 之后为__exit__
    print('然后进入我__exit__')
    file_one.close()
with contexts('yu.txt') as f:
    for i in f:
        print(i)

说明:

这段代码并不能实现异常处理,需要处理异常还是需要try...excetp...finally

import contextlib
@contextlib.contextmanager
def contexts(file_name):
    print('首先进入我__enter__')
    file_one=open(file_name,'r')

    try:
        yield file_one
    except (ValueError,Exception) as f :
        print(f)
    finally:
        file_one.close()
        return           

with contexts('yu.txt') as f:
    for i in f:
        i/0      #错误
        print(i)     #首先进入我__enter__
                        unsupported operand type(s) for /: 'str' and 'int'

总结:上下文管理工具重点在于yield ,在之前为__enter__,之后如为__exit__。在管理工具中管理资源可以这样,但是在处理异常的时候还是需要try...excetp...finally语句来实现。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值