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

    ref:

    https://docs.python.org/release/2.6/whatsnew/2.6.html#pep-343-the-with-statement

    https://www.ibm.com/developerworks/cn/opensource/os-cn-pythonwith/

    https://www.python.org/dev/peps/pep-0343/

    摘自文档:

    with替代了之前在python里使用try...finally来做清理工作的方法。基本形式如下:

    with expression [as variable]:
        with-block

    当expression执行的时候,返回一个支持context management protocol(有__enter__(), __exit__()方法)的对象

    这个对象的__enter__()方法在with-block执行运行,该方法返回的结果赋给variable(如果variable存在的话)

    with-block执行之,__exit__()方法被调用,在这里可以执行清理工作

    If BLOCK raises an exception, the __exit__(type, value, traceback)() is called with the exception details

    with语句的运行过程如下:

    mgr = (EXPR)
    exit = type(mgr).__exit__  # Not calling it yet
    value = type(mgr).__enter__(mgr)
    exc = True
    try:
        try:
            VAR = value  # Only if "as VAR" is present
            BLOCK
        except:
            # The exceptional case is handled here
            exc = False
            if not exit(mgr, *sys.exc_info()):
                raise
            # The exception is swallowed if exit() returns true
    finally:
        # The normal and non-local-goto cases are handled here
        if exc:
            exit(mgr, None, None, None)

    也就是说:

    如果执行过程中没有出现异常,或者语句体中执行了语句 break/continue/return,

    则以 None 作为参数调用 __exit__(None, None, None) ;

    如果执行过程中出现异常,则使用 sys.exc_info 得到的异常信息为参数调用 __exit__(exc_type, exc_value, exc_traceback)

    出现异常时,如果 __exit__(type, value, traceback) 返回 False,则会重新抛出异常,让with 之外的语句逻辑来处理异常,这也是通用做法;如果返回 True,则忽略异常,不再对异常进行处理

    支持context management protocol的python对象有file object, threading locks variables, localcontext() fucntion in decimal module

    在文档里,有一个连接数据库的例子(省略了部分非关键代码):

    class DatabaseConnection:
        # Database interface
        def cursor(self):
            "Returns a cursor object and starts a new transaction"
        def commit(self):
            "Commits current transaction"
        def rollback(self):
            "Rolls back current transaction"
        def __enter__(self):
            # Code to start a new transaction
            cursor = self.cursor()
            return cursor
        def __exit__(self, type, value, tb):
            if tb is None:
                # No exception, so commit
                self.commit()
            else:
                # Exception occurred, so rollback.
                self.rollback()
                # return False

    然后就可以这样使用了:

    db_connection = DatabaseConnection()
    with db_connection as cursor:
        cursor.execute('insert into ...')
        cursor.execute('delete from ...')
        # ... more operations ...
  • 相关阅读:
    linux下ipc
    c各种打印集合
    linux环境下,利用gsoap生成webservice客户端进行应用程序开发的小结 (轉)
    Linux C函数之错误处理函数
    Linux操作系统文件系统基础知识详解
    常用字符串操作函数
    ASP.NET偷懒大法二
    ASP.NET偷懒大法三 (利用Attribute特性简化多查询条件拼接sql语句的麻烦)
    用JavaScript获取Asp.net服务器端控件CheckBoxList的选中值数组
    ASP.NET偷懒大法四(动态生成表单对象)
  • 原文地址:https://www.cnblogs.com/geeklove01/p/9028909.html
Copyright © 2011-2022 走看看