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
  • 相关阅读:
    程序员的困境
    linux中获取系统时间 gettimeofday函数
    Vim 模式及常用命令整理
    使用stringstream进行类型转换与字符串分割
    EasyNet开源项目计划
    用Akka构建一个简易的分布式文件系统
    SolrCloud攻略
    EasyNet.Solr 4.4.0发布及例子
    axis2调用webservice
    Oracle常用函数2查询
  • 原文地址:https://www.cnblogs.com/xinyuefeiyang/p/7237249.html
Copyright © 2011-2022 走看看