"""
#[备注]
#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. 下载google play上最新版的apk

    注意,是下载最新版的方法,不是像很多网站下的是旧版本 http://techapple.net/2014/09/3-websites-directly-download-apk-google-play ...

  2. 万恶之源 - Python基础数据类型三

    字典 字典的简单介绍 字典(dict)是python中唯⼀的⼀个映射类型.他是以{ }括起来的键值对组成. 在dict中key是 唯⼀的.在保存的时候, 根据key来计算出⼀个内存地址. 然后将key ...

  3. [LeetCode] 152. Maximum Product Subarray_Medium tag: Dynamic Programming

    Given an integer array nums, find the contiguous subarray within an array (containing at least one n ...

  4. python三步实现人脸识别

    原文地址https://www.toutiao.com/a6475797999176417550 Face Recognition软件包 这是世界上最简单的人脸识别库了.你可以通过Python引用或者 ...

  5. jmeter处理带表单的接口请求

    如何用jmeter处理带选项的表单接口请求 下面是用到了F12 抓包的处理方法 下图是直接手动在页面上请求的结果 下面就是采用F12抓包抓到url 和FormData 分别把上面获取的url和Form ...

  6. iOS 新浪微博-1.0框架搭建

    项目搭建 1.新建一个微博的项目,去掉屏幕旋转 2.设置屏幕方向-->只有竖向 3.使用代码构建UI,不使用storyboard 4.配置图标AppIcon和LaunchImage 将微博资料的 ...

  7. C# 实现屏幕截屏

    //屏幕宽            int iWidth = Screen.PrimaryScreen.Bounds.Width;            //屏幕高            int iHe ...

  8. lnmp之mysql5.5.17安装

    先执行命令yum install cmake mysql5.5采用的是cmake安装(更先进的configure) wget下载目录(到清华大学的镜像站下载) [root@localhost loca ...

  9. linux脚本-判断进程是否存在,从而可以做预警处理..

    count=`ps -ef | grep Seeyon | grep -v "grep" | wc -l` echo $count if [ $count -gt 0 ]; the ...

  10. python-安装,设置环境变量(win10)

    python官网: https://www.python.org/ 选择需要的版本下载 下载后安装 我装的是默认位置C:\Python27 打开环境变量设置: 右键电脑--->属性----> ...