【Python】【上下文管理器】
"""
#[备注]
#1⃣️try :仅当try块中没有异常抛出时才运行else块。
#2⃣️for:仅当for循环运行完毕(即for循环没有被break语句终止)才运行else
#while:仅当while循环因为条件为假植而退出时(即while循环没有被break语句终止)才运行else
#即在所有情况下,如果异常或者return、break、或continue语句导致控制权跳到了复合语句的主块之外,else子句也会被跳过 #15。2 上下文管理器和with块
#上下文管理协议包含__enter__和__exit__两个方法。with语句开始运行时,会在上下文管理器对象上调用__enter__方法。with语句运行结束后,会在上下文管理器对象上调用__exit__方法,以此扮演finally子句的角色
#例子15-1
with open('__init__.py') as fp:
src = fp.read(60)
print(len(src)) #4
print(fp) #<_io.TextIOWrapper name='__init__.py' mode='r' encoding='UTF-8'>
print(fp.closed,fp.encoding) #True UTF-8
print(fp.read(60)) #ValueError: I/O operation on closed file. #例子15-2 强调上下文管理器与__enter__方法返回的对象之间的区别
class LookingClass:
def __enter__(self):# 除了SELF外,python调用__enter__方法时不传入其他参数
import sys
self.original_write = sys.stdout.write #往标准输出里写入数据,相当于print
sys.stdout.write = self.reverse_write #为sys.stdout.write打猴子补丁
return 'JABBERWOCKY'
def reverse_write(self,text):
self.original_write(text[::-1])
def __exit__(self, exc_type, exc_val, exc_tb): #exc_type 异常类(例如ZeroDivisionError)exc_value 异常实例。有时会有参数传给异常构造方法,例如错误消息,这些参数可以使用exc_value.args获取 traceback :traceback对象。
import sys # 重复倒入模块不会消耗很多资源,因为python会缓存有导入的模块
sys.stdout.write = self.original_write #还原原来的sys.stdout.write方法
if exc_type is ZeroDivisionError:
print('Please DO NOT divide by zero!')
return True #告诉解释器,异常已经解决
#如果__exit__方法返回None,或者True之外的值,with块中的任何异常都会向上冒泡
with LookingClass() as what: #上下文管理器是LookingClass类的实例,python在上下文管理器上调用__enter__方法,把结果绑定到what上
print('Alice,Kigtty and Snowdrop') #pordwonS dna yttgiK,ecilA
print(what) #YKCOWREBBAJ
print(what) #JABBERWOCKY 输出不再反向
print('Back to normal.') #Back to normal. 输出不再反向
#例子15-4 在with块之外使用LookingClass类
manager = LookingClass()
print(manager) #<__main__.LookingClass object at 0x10d593be0>
monster = manager.__enter__()
print(monster == 'JABBERWOCKY') #eurT
print(monster) #YKCOWREBBAJ
print(manager) #>8abfca001x0 ta tcejbo ssalCgnikooL.__niam__<
manager.__exit__(None,None,None)
print(monster) #JABBERWOCKY ##15.3 contextlib模块中的实用工具
#closing :如果对象提供了close()方法,但没有实现__enter__/__exit__协议,那么可以实用这个函数构建上下文管理器
#suppress 构建临时忽略指定异常的上下文管理器
#@contextmanager 这个装饰器把简单的生成器函数变成上下文管理器,这样就不用创建类取实现管理器协议了
#15.4 使用@contextmanager
#例子15-5 使用生成器实现的上下文管理器
import contextlib @contextlib.contextmanager
def looking_glass():
import sys
original_write = sys.stdout.write def reverse_write(text):
original_write(text[::-1]) sys.stdout.write = reverse_write
yield 'JABBERWOCKY'
sys.stdout.write = original_write
#例子15-6 测试
with looking_glass() as what:
print('Alice,Kitty and Snowdrop') #pordwonS dna yttiK,ecilA
print(what) #YKCOWREBBAJ
print(what) #JABBERWOCKY
#[分析]其实,contextlib.contextmanager 装饰器会把函数包装成实现__enter__和__exit__方法的类。这个类的__enter__方法有如下作用
#...1⃣️调用生成器函数,保存生成器对象(这里把它称为gen)
#...2⃣️调用next(gen),执行到yield关键字所在的位置
#...3⃣️返回next(gen)产出的值,以便把产出的值绑定到with/as语句中的目标变量上。
#...with 块终止时,__exit__方法会作以下几件事
#...1⃣️检查有没有把异常传给exc_type;如果有,调用gen.throw(exception),在生成器函数定义体中包含yield关键字的那一行抛出异常
#...2⃣️否则,嗲用next(gen),继续执行生成器函数定义体中yield之后的代码
#【注意】上面的例子有一个严重的错误:如果发生异常,python解释器会将其捕获,然后在looking_glass函数的yield表达式里再次抛出。但是,那里没有处理错误的代码,因此looking_glass函数会中止,永远无法恢复成原来的sys.stdout.write方法,导致系统处于无效状态
# 例子15-7 基于生成器的上下文管理器,而且实现了异常处理- """ import contextlib
@contextlib.contextmanager
def looking_glass():
import sys
original_write = sys.stdout.write def reverse_write(text):
original_write([text[::-1]]) sys.stdout.write = reverse_write msg = ''
try:
yield 'JABBERWOCKY'
except ZeroDivisionError :
msg = 'Please DO NOT divede by zero!'
finally:
sys.stdout.write = original_write
if msg:
print(msg)
【Python】【上下文管理器】的更多相关文章
- python 上下文管理器
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 上下文管理器(context manager)是Python2.5开始支持的一种语 ...
- Python 上下文管理器和else块
最终,上下文管理器可能几乎与子程序(subroutine)本身一样重要.目前,我们只了解了上下文管理器的皮毛--Basic 语言有with 语句,而且很多语言都有.但是,在各种语言中 with 语句的 ...
- Python上下文管理器
在Python中让自己创建的函数.类.对象支持with语句,就实现了上线文管理协议.我们经常使用with open(file, "a+") as f:这样的语句,无需手动调用f.c ...
- python上下文管理器ContextLib及with语句
http://blog.csdn.net/pipisorry/article/details/50444736 with语句 with语句是从 Python 2.5 开始引入的一种与异常处理相关的功能 ...
- Python上下文管理器 with
对于系统资源的操作,如:文件操作.数据库操作等,我们往往打开文件.连接数据库后忘了将其close掉,这时就可能会引发异常,因此我们常用的做法是: # coding:utf-8 f = open(&qu ...
- Python上下文管理器(Context managers)
上下文管理器(Context managers) 上下文管理器允许你在有需要的时候,精确地分配和释放资源. 使用上下文管理器最广泛的案例就是with语句了.想象下你有两个需要结对执行的相关操作,然后还 ...
- python上下文管理器细读
test 1 上下文管理器,将生成器转化为上下文管理器 import contextlib @contextlib.contextmanager def a(): print(1) yield pri ...
- 吃透Python上下文管理器
什么是上下文管理器? 我们常见的with open操作文件,就是一个上下文管理器.如: with open(file, 'rb') as f: text = f.read() 那上下文管理器具体的定义 ...
- python 上下文管理器contextlib.ContextManager
1 模块简介 在数年前,Python 2.5 加入了一个非常特殊的关键字,就是with.with语句允许开发者创建上下文管理器.什么是上下文管理器?上下文管理器就是允许你可以自动地开始和结束一些事情. ...
- Python 上下文管理器模块--contextlib
在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...
随机推荐
- Selenium+Java元素定位之一
通过id进行定位 driver.findElement(By.id("kw")).sendKeys("博客园"); 通过name进行定位 driver.find ...
- etcd 集群部署
etcd web管理 https://nikfoundas.github.io/etcd-viewer/ # git clone https://github.com/nikfoundas/etcd- ...
- testng入门教程1在testng运行一个简单的testcase
在eclips运行java,创建一个Java类文件名TestNGSimpleTest C:\ > TestNG_WORKSPACE import org.testng.annotations. ...
- html05
1.js中的对象-内置对象-外部对象-自定义对象 2.常见的内置对象有哪些?-String对象-Number对象-Boolean对象-Array对象-Math对象-Date对象-RegExp正则对象- ...
- 软件包管理:rpm命令管理-包命名与依赖性
rpm包的管理主要有两种方法:一种是rpm命令管理另一种是yum在线管理 注意软件包没有扩展名,写上只是为了好看,便于识别而已. 注意区别包名,包全名.之所以要区分,就是因为有些命令十分挑剔,需要跟正 ...
- 你真的了解[super ]关键字吗?
前言 此篇文章是看了阮老师的es6教程,看到super关键字的时候觉得有必要总结梳理一下,原文还是参考 ECMAScript 6入门. 正文 super 这个关键字,既可以当作函数使用,也可以当作对象 ...
- Webform和MVC,为什么MVC更好一些?(转)
转自http://www.admin10000.com/document/5277.html 前言 如果你看了最近微软的议程,你会发现他们现在的焦点除了MVC,还是MVC.问题在于为什么微软如此热衷于 ...
- uva1330 在一个大的矩阵中寻找面积最大的子矩阵
大白书 P50页 #include <algorithm> #include <cstdio> using namespace std; ; int ma[maxn][maxn ...
- Loadrunder场景设计篇——添加windows Resource计数器和指标说明
目的 监控要测试的windows服务器的资源使用情况 A.添加计数器步骤 1.添加视图,方法双击.拖动左侧的Windows Rescources到右边图形区,或右键右侧已有视图,Open a New ...
- linux常用命令:iostat 命令
Linux系统中的 iostat 是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视.它的特点是汇报磁盘活动统计情况,同时也会 汇报出CPU使用情况 ...