zoukankan      html  css  js  c++  java
  • python中的with语句

    python中的with语句使用于对资源进行访问的场合,保证不管处理过程中是否发生错误或者异常都会执行规定的__exit__(“清理”)操作,释放被访问的资源,比如有文件读写后自动关闭、线程中锁的自动获取和释放等。

    与python中with语句有关的概念有:上下文管理协议、上下文管理器、运行时上下文、上下文表达式、处理资源的代码段。

    with语句的语法格式如下:

    with context_expression [as target(s)]:
        with-body

    with语句的执行原理:

    context_manager=context_expression
    exit=type(context_manager).__exit__
    value=type(context_manager).__enter__(context_manager)
    exc=True
    try:
        try:
            targer=value
            with-body
        except:
            exc=False
            if not exit(context_manager, *sys.exc_info()):
                raise
    finally:
        if exc:
            exit(context_manager,None,None,None)

    从with的执行原理中可以看出,context_expression返回的对象中必须具有__exit__和__enter__两个方法,而且先检查__exit__方法在检查__enter__方法。无论在执行with-body中的函数体的过程中是否会发生异常,都会执行__exit__函数,如果没有异常,退出函数的中参数都为None;如果发生异常,则使用sys.exc_info()返回的异常信息为参数退出,并且当__exit__方法返回True时,忽略异常,当__exit__方法返回False时,抛出异常,此时,__exit__函数中就不需要再抛出异常,只需要将__exit__函数的返回值设为False就可以了。

    例子:

     自定义支持上下文管理协议的类:

    不抛出异常的函数体:

    抛出异常的函数体:

    python提供了contextlib模块,省去了写__enter__和__exit__重复工作了。contextlib模块提供了3个对象:contextmanager装饰器、上下文管理器closing和nested函数。

    装饰器contextmanager用来对生成器函数进行装饰,生成器函数被装饰以后,返回的是一个上下文管理器。

     

      yield语句之前的代码在__enter__函数中执行,yield语句之后的代码在__exit__函数中执行。

    closing上下文管理器包装起来的对象必须提供close()方法。

      closing的执行原理如下:

    class closing(object):
        def __init__(self,thing):
            self.thing = thing
        def __enter__(self):
            return self.thing
        def __exit__(self, *exc_info):
            self.thing.close()

      因此,closing上下文管理器包装的对象必须提供close()函数。

    nested函数可以将多个上下文管理器组织在一起,避免使用嵌套的with语句。  

    with nested(A(),B(),C()) as (X,Y,Z):
        with-body

    类似于:

    with A() as X:
        with B() as Y:
            with C() as Z:
                with-body
  • 相关阅读:
    查看mysql服务器连接
    读懂MySQL执行计划
    学会MySQL索引
    记一个有趣的Java OOM!
    高并发场景系列(一) 利用redis实现分布式事务锁,解决高并发环境下减库存
    如何优雅的使用mybatis
    禁止页面后退JS(兼容各浏览器)
    如何做一个对账系统
    centos7.2进入单用户模式修改密码
    linux系统引导流程
  • 原文地址:https://www.cnblogs.com/xinyuefeiyang/p/7237249.html
Copyright © 2011-2022 走看看