Python中With的用法
在看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申明的执行过程如下:
- 计算出内容表达式(context expression)以获取内容管理(context manager),该表达式是在with_item中给出的expression。
- 内容管理器(context manager)加载__exit__()方法以备之后使用
- 内容管理器(context manager)触发__enter__()方法
- 假如一个目标(with_item)包含在with申明中,那么__enter__()的返回值将赋值给该目标。注意:With申明保证如果__enter__()函数的执行没有报错,那么__exit__()将总是执行。 如果在赋值给目标(with_item)的过程中出错,那么被视作该错误是在执行程序组中发生的。参考第六步
- 执行程序组(suite)
- 内容管理器(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的用法的更多相关文章
- python 中del 的用法
python中的del用法比较特殊,新手学习往往产生误解,弄清del的用法,可以帮助深入理解python的内存方面的问题. python的del不同于C的free和C++的delete. 由于pyth ...
- python中argparse模块用法实例详解
python中argparse模块用法实例详解 这篇文章主要介绍了python中argparse模块用法,以实例形式较为详细的分析了argparse模块解析命令行参数的使用技巧,需要的朋友可以参考下 ...
- 【313】python 中 print 函数用法总结
参考:python 中 print 函数用法总结 参考:Python print() 函数(菜鸟教程) 参考:Python 3 print 函数用法总结 目录: 字符串和数值类型 变量 格式化输出 p ...
- python中MySQLdb模块用法实例
篇文章主要介绍了python中MySQLdb模块用法,以实例形式详细讲述了MySQLdb模块针对MySQL数据库的各种常见操作方法,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了python中 ...
- python中hashlib模块用法示例
python中hashlib模块用法示例 我们以前介绍过一篇Python加密的文章:Python 加密的实例详解.今天我们看看python中hashlib模块用法示例,具体如下. hashlib ha ...
- Python Deque 模块使用详解,python中yield的用法详解
Deque模块是Python标准库collections中的一项. 它提供了两端都可以操作的序列, 这意味着, 你可以在序列前后都执行添加或删除. https://blog.csdn.net/qq_3 ...
- Python中super的用法【转载】
Python中super的用法[转载] 转载dxk_093812 最后发布于2019-02-17 20:12:18 阅读数 1143 收藏 展开 转载自 Python面向对象中super用法与MRO ...
- Python中AND-OR的用法
学习Python中的lambda函数的时候,才发现原来Python中的AND和OR还可以有一些别的用法.Python中的布尔逻辑计算的结果并非返回布尔值,而是返回它们相互之间的某一个.文章的部分例子来 ...
- python中的有趣用法
本文给除了python中几个有趣的用法,可以给我们不一样的启发 1: Python中模拟使用C++ 中的 cout << import sys class ostream: def ...
随机推荐
- C#当中的多线程_任务并行库(下)
4.8 处理任务中的异常 下面这个例子讨论了任务当中抛出异常,以及任务异常的获取 class Program { static void Main(string[] a ...
- JavaScript Invalid Date Verify
if ( Object.prototype.toString.call(d) === "[object Date]" ) { // it is a date if ( isNaN( ...
- 【BZOJ1875】【矩阵乘法】[SDOI2009]HH去散步
Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因 ...
- ecshop 函数列表大全
lib_time.phpgmtime() P: 获得当前格林威治时间的时间戳 /$0server_timezone() P: 获得服务器的时区 /$0local_mktime($hour = NULL ...
- Island of Survival 概率
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> ...
- mouseover和mouseout事件在鼠标经过子元素时也会触发
JavaScript的mouseover和mouseout事件,在绑定元素内部有子元素的情况下, 经过绑定元素时会多次触发mouseover和mouseout事件. jQuery解决办法: jquer ...
- thinkphp中表有前缀名的时候申明模板的方法
$Model=new \Home\Model\Stu_activityModel; $Model=D('Stu_activity');//错误的声明不了
- 【JQuery学习历程】1.初识JQuery
1.JQuery简介: JQuery是用js写的JavaScript库,是为了简化js对HTML元素的操作.实现动画效果并方便为网站提供ajax交互: 2.ready()方法: ready()方法和j ...
- JavaScript学习总结【10】、DOM 事件
DOM 事件是 JS 中比较重要的一部分知识,所谓事件,简单理解就是用户对浏览器进行的一个操作.事件在 Web 前端领域有很重要的地位,很多重要的知识点都与事件有关,所以学好 JS 事件可以让我们在J ...
- node.Js学习-- 创建服务器简要步骤
1.创建项目目录 mkdir ningha(文件夹名)npm init 初始化项目 获得package.json 2..在node.Js命令行操作进入到文件所在目录 3.输入browser-sync ...