在看Dive Into Python中有关描述文件读写那章节的时候,看到了有关with的用法,查阅下相关资料,记录下来,以备后用。

官方的reference上有关with statement是这样说的,With申明把由context manager定义的方法的执行块包装起来。这样可以把try...except...finally的使用模式封装起来已被之后方便重用。

官方的定义如下:

 with_stmt ::=  "with" with_item ("," with_item)* ":" suite
with_item ::= expression ["as" target]

只有一个"item"的with申明的执行过程如下:

  1. 计算出内容表达式(context expression)以获取内容管理(context manager),该表达式是在with_item中给出的expression。
  2. 内容管理器(context manager)加载__exit__()方法以备之后使用
  3. 内容管理器(context manager)触发__enter__()方法
  4. 假如一个目标(with_item)包含在with申明中,那么__enter__()的返回值将赋值给该目标。注意:With申明保证如果__enter__()函数的执行没有报错,那么__exit__()将总是执行。 如果在赋值给目标(with_item)的过程中出错,那么被视作该错误是在执行程序组中发生的。参考第六步
  5. 执行程序组(suite)
  6. 内容管理器(context manager)中的__exit__()方法触发。假如程序组中出现异常或错误,那对应的type,value,以及traceback全部传入__exit__()方法中去。否则,三个None值传入方法中去。

如果程序组中由于异常退出了,并且__exit__()的返回值为假,那么该异常重新引发。假如返回值为真,那么忽略该异常,继续执行With申明之后的程序。

如果程序组中并非由于异常退出,忽略__exit__()的返回值,该干嘛干嘛。

多个目标(with_item)在with申明中的情况,内容管理器(context manager)将其看做多个with申明嵌套。例子如下:

 with A() as a, B() as b:
suite

同于:

 with A() as a:
with B() as b:
suite

以上是With申明具体的内部执行过程,可以看出,其中最核心是内容管理器(context manager),所以我又查阅了有关with申明的内容管理器(with statment context managers)的相关内容。

Context Manager主要是用来管理在with申明中定义的运行时内容(runtime context),也可以说是一种环境,一个状态。 该管理器实现了两个方法,一个是__enter__()方法,一个是__exit__()方法。

__enter__()方法主要是进入运行时内容(runtime context)并返回与之相对应的对象。 该方法的返回值的会绑定到使用该context Manager的with申明AS标识符之后的内容。举个例子:

 with open(r'D:/test.txt', 'r', encoding='utf-8') as a_file:
process(a_file)

该内容管理器(context manager)中的__enter__()方法返回的是一个文件对象,该对象赋值给了a_file。

在举个例子,浮点型数据运算时需要设定一个计算环境(contexts),该环境可以设定精度,进位的规则,决定哪些中情况视为异常,限制指数范围等等。可以使用getcontext()和setcontext()方法来实现,也可以用localcontext() 和with申明结合的方法来实现。

 from decimal import localcontext

 with localcontext() as ctx:
ctx.prec = 42 # Perform a high precision calculation
s = calculate_something()
s = +s # Round the final result back to the default precision

__exit__(exc_type, exc_val, exc_tb)方法就是退出这个运行时内容或环境(runtime context)并返回一个布尔值的变量来确定是否忽略中途出现的异常情况。如果中途在with申明中的执行体中出现了什么问题。就会把对应的异常类型,值以及回溯信息传给该方法,没有异常就传入None。如果有异常传入并且布尔值为真就忽略该异常,如果有异常传入但布尔值为假就像正常一样抛出异常。内容管理器的好处就如之前所说一样就是把try...except...finally的使用模式封装起来已被之后方便重用。

有关contextlib的内容将之后更新。

Python中With的用法的更多相关文章

  1. python 中del 的用法

    python中的del用法比较特殊,新手学习往往产生误解,弄清del的用法,可以帮助深入理解python的内存方面的问题. python的del不同于C的free和C++的delete. 由于pyth ...

  2. python中argparse模块用法实例详解

    python中argparse模块用法实例详解 这篇文章主要介绍了python中argparse模块用法,以实例形式较为详细的分析了argparse模块解析命令行参数的使用技巧,需要的朋友可以参考下 ...

  3. 【313】python 中 print 函数用法总结

    参考:python 中 print 函数用法总结 参考:Python print() 函数(菜鸟教程) 参考:Python 3 print 函数用法总结 目录: 字符串和数值类型 变量 格式化输出 p ...

  4. python中MySQLdb模块用法实例

    篇文章主要介绍了python中MySQLdb模块用法,以实例形式详细讲述了MySQLdb模块针对MySQL数据库的各种常见操作方法,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了python中 ...

  5. python中hashlib模块用法示例

    python中hashlib模块用法示例 我们以前介绍过一篇Python加密的文章:Python 加密的实例详解.今天我们看看python中hashlib模块用法示例,具体如下. hashlib ha ...

  6. Python Deque 模块使用详解,python中yield的用法详解

    Deque模块是Python标准库collections中的一项. 它提供了两端都可以操作的序列, 这意味着, 你可以在序列前后都执行添加或删除. https://blog.csdn.net/qq_3 ...

  7. Python中super的用法【转载】

    Python中super的用法[转载] 转载dxk_093812 最后发布于2019-02-17 20:12:18 阅读数 1143  收藏 展开 转载自 Python面向对象中super用法与MRO ...

  8. Python中AND-OR的用法

    学习Python中的lambda函数的时候,才发现原来Python中的AND和OR还可以有一些别的用法.Python中的布尔逻辑计算的结果并非返回布尔值,而是返回它们相互之间的某一个.文章的部分例子来 ...

  9. python中的有趣用法

    本文给除了python中几个有趣的用法,可以给我们不一样的启发 1: Python中模拟使用C++ 中的   cout << import sys  class ostream: def  ...

随机推荐

  1. sql - 查询所有表中包含指定值

    可以直接创建sql语句: CREATE TABLE qResults (tName nvarchar(370), cname nvarchar(3630),[count] int) declare @ ...

  2. oracle 权限管理

    系统权限 系统权限需要授予者有进行系统级活动的能力,如连接数据库,更改用户会话.建立表或建立用户等等.你可以在数据字典视图SYSTEM_PRIVILEGE_MAP上获得完整的系统权限.对象权限和系统权 ...

  3. Java中报错No enclosing instance of type caiquan is accessible. Must qualify the allocation with an enclosing instance of type caiquan (e.g. x.new A() where x is an instance of caiquan).

    package test;import java.util.Scanner;import java.util.Random;public class caiquan { public static v ...

  4. ES 必备插件的安装

    1. elasticsearch-head插件的安装,非常好的插件 elasticsearch-head是一个elasticsearch的集群管理工具,它是完全由html5编写的独立网页程序,你可以通 ...

  5. 取消IE“已限制此网页运行可以访问计算机的脚本,转自“园封记忆”

    为了有利于保护安全性,IE已限制此网页运行可以访问计算机的脚本或 ActiveX 控件.请单击这里获取选项... 方法一: 在本地调试html页,如果其中包含js或flash,IE经常会提示“IE已限 ...

  6. 『重构--改善既有代码的设计』读书笔记----Replace Array with Object

    如果你有一个数组,其中的元素各自代表不同东西,比如你有一个 QList<QString> strList; 其中strList[0]代表选手姓名,strList[1]代表选手家庭住址,很显 ...

  7. Setup FTP Server On CentOS, RHEL, Scientific Linux 6.5/6.4/6.3

    setsebool allow_ftpd_full_access onsetsebool -P ftp_home_dir on vsftpd (Very Secure File Transport P ...

  8. nRF52系列——Get started

    Install Jlink Install MDK 这里的使用的是MDK 5.14 Install SDK https://developer.nordicsemi.com/nRF52_SDK/ 这里 ...

  9. MySQL驱动阅读------executeQuery查询的过程,基于JDBC-----5.1.26

    Statement statement = connection.createStatement(); final ResultSet resultSet = statement.executeQue ...

  10. php100视频教程解压密码

    php100-75-vip.rar 解压密码:php100-18293-2938-2839-348-#php100-76_u.rar 解压密码:php100-18634-6254-1001-283-# ...