"""
#[备注]
#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. [LeetCode] 331. Verify Preorder Serialization of a Binary Tree_Medium tag: stack

    One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, ...

  2. Postman使用js获取日期

    在用postman进行接口自动化测试的时候,某个查询接口需要使用到日期参数进行请求: 假设当前日期为2018-05-07 10:30:20 ,需要传的日期为: beginTime:2018-05-01 ...

  3. python sys.path[0] 的解释

    sys.path是python的搜索模块的路径集,返回的结果是一个list path[0] 此列表的第一项,path[0],在程序启动时初始化,是包含用来调用Python解释器的脚本的目录.如果脚本目 ...

  4. 一个新人对HTML的理解

    首先 HTML里面包含的东西是什么? 在HTML里面   注释的表示方式是    <!--注释内容--> 注释 HTML初始默认包含了两大部分: 一部分是 <head>< ...

  5. JQ 给textarea赋值

    <textarea id='t1'></textarea> 下面是 jq赋值的三种方式 $("#t1").text("AAA"); $( ...

  6. Devenv 命令行开关

    Devenv 可用来设置集成开发环境 (IDE) 的各个选项,以及从命令行生成.调试和部署项目.使用这些开关从脚本或 .bat 文件(例如每夜生成的脚本)运行 IDE,或以特定配置启动 IDE. 说明 ...

  7. Azkaban 入门

    需求 实际当中经常有这些场景:每天有一个大任务,这个大任务可以分成A,B,C,D四个小任务,A,B任务之间没有依赖关系,C任务依赖A,B任务的结 果,D任务依赖C任务的结果.一般的做法是,开两个终端同 ...

  8. python 练习用python六剑客实现一个统计数字的个数,六剑客:(map、lambda、reduce、filter、切片、推到列表)

    统计一共有几个数字 s="sdfa45ads46723" #lambda >>> filter(lambda x:x.isdigit(),list(s)) ['4 ...

  9. Linux基础命令---mktemp

    mktemp 创建临时文件或者目录,这样的创建方式是安全的.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法       mk ...

  10. 微信小程序的功能开发工具跟公众号的差别,小程序是一种减负思维对简单APP是巨大打击

    微信小程序的功能开发工具跟公众号的差别,小程序是一种减负思维对简单APP是巨大打击 摘要: 小程序和公众号最大的区别有如下四点:1.小程序没有粉丝,开发者在后台能看到的只能是累计用户访问数以及实时统计 ...