上下文管理器——with语句的实现
前言
with语句的使用给我们带来了很多的便利,最常用的可能就是关闭一个文件,释放一把锁。
既然with语句这么好用,那我也想让我自己写的代码也能够使用with语句,该怎么实现?
下面具体介绍怎样实现一个自己的with语句
使用类实现
要想使用with语句,那就要遵循with语句的使用规矩,也就是上下文管理器协议
这个协议提示我们要在类中去实现两个特殊方法,enter(self)和exit(self, exc_type, exc_val, exc_tb)
有了这两个方法,就可以使用with语句执行了,它的执行过程为先执行enter(self)方法,然后执行你添加在with下的代码,然后最后执行exit方法
如果在执行的过程中出现了异常,那么会自动执行exit方法,
class ErrorProduce:
def __init__(self):
pass
def produce(self):
raise RuntimeError('ERROR')
class MyWith:
def __enter__(self):
return ErrorProduce()
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type:
print("有错")
#print(exc_val)
#return True
else:
print("完美执行")
with MyWith() as E:
E.produce()
将上述代码运行,会先打印出“有错”,然后再打印出相关错误,然后程序由于错误终止,也就是说,在产生了错误后,还是执行了exit中的代码
如果将exit中的两个注释符号去掉的话,那么再次运行程序不会报错,但会将exc_val中的错误信息打印出来,这里相当于通过exit方法将错误抹除掉了,抹除方式为返回True,但也把with中抛出错误后的所有代码都跳过了。
使用函数实现
通过引入contextlib模块中的contextmanager装饰器,装饰函数使函数可以使用with语句
from contextlib import contextmanager
class ErrorProduce:
def __init__(self):
pass
def produce(self):
raise RuntimeError('ERROR')
@contextmanager
def my_with():
try:
yield ErrorProduce()
except Exception as e:
print(e)
#raise
finally:
print('收尾')
with my_with() as E:
E.produce()
print('aa')
函数中使用了yield,那么它也就变成了生成器,通过yield来划分相当于类中的enter和exit,yield返回的值也就是可以用作as后的值
上段代码中我们发现使用了try,except,finally异常处理的语句,这些语句是必要的吗?
通过测试,如果没有这些异常处理,那么with语句还是可以执行的,这里的意思是可以使用with语句,不会报不能使用with的错误,但是使用后,只有with下的语句中没有抛出异常,那么yield语句后边的代码才会执行,一旦有异常抛出,仍然是程序运行终止。所以,一般还是要配合try,except,finally语句来构造。
还有一点要注意,使用这种方式,异常被except捕捉后,那么这个异常就失效了,一般的我们还是会需要在except中再次将捕捉的异常抛出,也就是在后面加上raise,因为我们使用with只是为了做好一个收尾,如关闭文件句柄。或者另一种方式,我们干脆就不写except语句,直接写finally语句了。
- 文章中出现的棕色加粗的单词,是由于markdown-here将特殊方法两边的下划线转换产生的,原意为特殊方法
上下文管理器——with语句的实现的更多相关文章
- python2.7高级编程 笔记一(Python中的with语句与上下文管理器学习总结)
0.关于上下文管理器上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象. with manager as var: do_something(var) 相当于以 ...
- with/as上下文管理器
# -*- coding: utf-8 -*- #python 27 #xiaodeng #Python学习手册 868 #with/as上下文管理器 #with语句的基本格式: with open( ...
- Python中的上下文管理器(contextlib模块)
上下文管理器的任务是:代码块执行前准备,代码块执行后收拾 1 如何使用上下文管理器: 打开一个文件,并写入"hello world" filename="my.txt&q ...
- 【Python学习笔记】with语句与上下文管理器
with语句 上下文管理器 contextlib模块 参考引用 with语句 with语句时在Python2.6中出现的新语句.在Python2.6以前,要正确的处理涉及到异常的资源管理时,需要使用t ...
- python上下文管理器及with语句
with语句支持在一个叫上下文管理器的对象的控制下执行一系列语句,语法大概如下: with context as var: statements 其中的context必须是个上下文管理器,它实现了两个 ...
- Python中的上下文管理器和with语句
Python2.5之后引入了上下文管理器(context manager),算是Python的黑魔法之一,它用于规定某个对象的使用范围.本文是针对于该功能的思考总结. 为什么需要上下文管理器? 首先, ...
- python上下文管理器ContextLib及with语句
http://blog.csdn.net/pipisorry/article/details/50444736 with语句 with语句是从 Python 2.5 开始引入的一种与异常处理相关的功能 ...
- python之with语句结合上下文管理器
所谓上下文管理器即在一个类中重写了__enter__方法和__exit__方法的类就可以成为上下文管理器类. 我们可以通过with语句结合上下文管理器简化一些操作. 使用with语句结合自定义上下文管 ...
- Python核心技术与实战——二一|巧用上下文管理器和with语句精简代码
我们在Python中对于with的语句应该是不陌生的,特别是在文件的输入输出操作中,那在具体的使用过程中,是有什么引伸的含义呢?与之密切相关的上下文管理器(context manager)又是什么呢? ...
随机推荐
- F#周报2019年第17期
新闻 .NET版本的Apache Spark Apache Spark预览版介绍 F# Apache Spark示例 微软Build 2019大会(5月6日至8日) Rider用于F#的解决方案内的重 ...
- SQL 必知必会·笔记<2>检索和排序数据
1.检索数据 使用SELECT 检索表数据,必须至少给出两条信息——想选择什么, 以及从什么地方选择. 检索不同的值 使用DISTINCT关键字,检索不同的值,使用示例: SELECT DISTINC ...
- Spring Boot + Spring Cloud 构建微服务系统(一):服务注册和发现(Consul)
使用Consul提供注册和发现服务 什么是 Consul Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其它分布式服务注册与发现的方案,Consul ...
- LearnOpenGL学习笔记(六)——纹理单元
#version 330 core out vec4 FragColor; in vec3 ourColor; in vec2 TexCoord; uniform sampler2D ourTextu ...
- Structs+Spring+Hibernate快速入门
Structs+Spring+Hibernate,这是很经典的一个搭配,它的开发流程也比较程式化,下面以用户注册为例. 注册页面代码: <%@page contentType=" ...
- js中的模块化
前阵子一直忙着找实习,发现已经有一段时间没写博客了,面试很多时候会被问到模块化,今天就让我们一起来总结下把 一.什么是模块化 在js出现的时候,js一般只是用来实现一些简单的交互,后来js开始得到重视 ...
- [Luogu 3613] 睡觉困难综合征
Description 给定一棵 \(n\) 个点的树,每个点上有位运算 \(opt\) 和一个权值 \(x\),位运算有 &,|,^ 三种. 要求支持: 修改点 \(v\) 的 \(opt\ ...
- GNU μC/OS-II 在 S3C2440 上中断的实现
上一篇文章介绍了S3c2440的中断体系结构,今天我们来分析一下GNU-uC/OS-II在S3c2440上中断的实现. 首先找到IRQ的中断的向量,位于 2440init.S : OK ,我们通过名字 ...
- SQL 两个时间获取相差秒数
SELECT DATEDIFF(SECOND, '2005-12-31 23:59:00', '2006-01-01 00:00:00');
- LInux Crontab及命令
定时任务(cron job)被用于安排那些需要被周期性执行的命令.利用它,你可以配置某些命令或者脚本,让它们在某个设定的时间内周期性地运行.cron 是 Linux 或者类 Unix 系统中最为实用的 ...