"""
#[备注]
#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】【上下文管理器】的更多相关文章

  1. python 上下文管理器

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 上下文管理器(context manager)是Python2.5开始支持的一种语 ...

  2. Python 上下文管理器和else块

    最终,上下文管理器可能几乎与子程序(subroutine)本身一样重要.目前,我们只了解了上下文管理器的皮毛--Basic 语言有with 语句,而且很多语言都有.但是,在各种语言中 with 语句的 ...

  3. Python上下文管理器

    在Python中让自己创建的函数.类.对象支持with语句,就实现了上线文管理协议.我们经常使用with open(file, "a+") as f:这样的语句,无需手动调用f.c ...

  4. python上下文管理器ContextLib及with语句

    http://blog.csdn.net/pipisorry/article/details/50444736 with语句 with语句是从 Python 2.5 开始引入的一种与异常处理相关的功能 ...

  5. Python上下文管理器 with

    对于系统资源的操作,如:文件操作.数据库操作等,我们往往打开文件.连接数据库后忘了将其close掉,这时就可能会引发异常,因此我们常用的做法是: # coding:utf-8 f = open(&qu ...

  6. Python上下文管理器(Context managers)

    上下文管理器(Context managers) 上下文管理器允许你在有需要的时候,精确地分配和释放资源. 使用上下文管理器最广泛的案例就是with语句了.想象下你有两个需要结对执行的相关操作,然后还 ...

  7. python上下文管理器细读

    test 1 上下文管理器,将生成器转化为上下文管理器 import contextlib @contextlib.contextmanager def a(): print(1) yield pri ...

  8. 吃透Python上下文管理器

    什么是上下文管理器? 我们常见的with open操作文件,就是一个上下文管理器.如: with open(file, 'rb') as f: text = f.read() 那上下文管理器具体的定义 ...

  9. python 上下文管理器contextlib.ContextManager

    1 模块简介 在数年前,Python 2.5 加入了一个非常特殊的关键字,就是with.with语句允许开发者创建上下文管理器.什么是上下文管理器?上下文管理器就是允许你可以自动地开始和结束一些事情. ...

  10. Python 上下文管理器模块--contextlib

    在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...

随机推荐

  1. HTTP头部信息解释分析(详细整理)

    这篇文章为大家介绍了HTTP头部信息,中英文对比分析,还是比较全面的,若大家在使用过程中遇到不了解的,可以适当参考下 HTTP 头部解释 1. Accept:告诉WEB服务器自己接受什么介质类型,*/ ...

  2. 在vue init webpack my-project卡住的问题

    在安装完node.js后,也用cnpm代替了npm,然后使用cnpm在node.js的安装路径下安装了vue-cli:cnpm install --global vue-cli.然后使用vue ini ...

  3. PAT 1019 General Palindromic Number[简单]

    1019 General Palindromic Number (20)(20 分) A number that will be the same when it is written forward ...

  4. 【java】System.out重定向到文件,并重定向会console上

    重定向到文件: System.setOut(new PrintStream(new File("data\\train.1.scale"))); 重定向回console: //把输 ...

  5. [LeetCode] 221. Maximal Square _ Medium Tag: Dynamic Programming

    Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and re ...

  6. vs计算代码行数

    1.用vs打开程序 2.编辑——查找——在文件中查找 3.查找内容^b*[^:b#/]+.*$   应用正则表达式,在整个解决方案中,文件类型空 4.查找全部,仔细盯着右下角数字,查找完毕后会自动消失 ...

  7. python学习第一次

    一,安装python 官网下载地址:https://www.python.org/downloads/windows/ 我下载的是最新的: Download Windows x86 web-based ...

  8. UVM中Callback机制

    Callback机制,其实是使用OOP来实现的一种程序开发者向程序使用者提供的模块内部的接口.可以在Test_case的高度改变其他component的一些行为. Systemverilog中已经提供 ...

  9. Solr安装中文分词器IK

    安装环境 jdk1.7 solr-4.10.3.tgz KAnalyzer2012FF_u1.jar tomcat7 VM虚拟机redhat6.5-x64:192.168.1.201 Xshell4 ...

  10. 数据仓库基础(六)数据的ETL

    本文转载自:http://www.cnblogs.com/evencao/p/3140487.html ETL是数据抽取(Extract).转换(Transform).加载(Load)的简写,是构建数 ...