在看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. My97 DatePicker 选择时间后弹出选择的时间

    项目中用到这个时间插件,注册用户时可以选中永久和选择时间,二者是互斥关系, 所以在选择时间插件时,需要绑定一个事件,所以看到了这个插件: <input id="yydate" ...

  2. Sql Server内置函数实现MD5加密

    实例 MD5加密“123456”: HashBytes('MD5','123456') 结果:0xE10ADC3949BA59ABBE56E057F20F883E (提示:看完最后,结果要进行转换.) ...

  3. Fibonacci 数列递归 重复计算

    public class Fibonacci{ public static long F(long n){ System.out.println("call F" + n); ) ...

  4. ACM YTU 《挑战编程》第一章 入门 Problem E: Graphical Editor

    Description Graphical editors such as Photoshop allow us to alter bit-mapped images in the same way ...

  5. 【转】Eclipse工具使用技巧总结

    作者:Work Hard Work Smart 出处:http://www.cnblogs.com/linlf03/ 可参考http://www.codeceo.com/article/eclipse ...

  6. python【第十二篇】Mysql基础

    内容: 1.数据库介绍及MySQL简介 2.MySQL基本操作 1 数据库介绍 1.1什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同 ...

  7. js代码判断浏览器种类IE、FF、Opera、Safari、chrome及版本

    这篇文章主要分享了判断IE.FF.Opera.Safari.Chrome等浏览器和版本的两种方法,需要的朋友可以参考下 因为ie10-ie11的版本问题,不再支持document.all判断,所以ie ...

  8. BZOJ 3992 序列统计

    Description 小C有一个集合\(S\),里面的元素都是小于\(M\)的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为\(N\)的数列,数列中的每个数都属于集合\(S\). 小C用 ...

  9. BZOJ 1026 windy数

    Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? In ...

  10. 完美解决 Phonegap jQeuryMobile 闪屏 问题

    在切换page或者弹出dialog时,会出现闪屏情况,综合网络上各种方法,得出以下方法可完美解决: 1.首先界面页面切换闪屏: 在加载jQuery后,加载jQuery Mobiel之前,插入js语句进 ...