python之简述上下文管理
上下文管理器
原理
上下文管理能保证资源会被正确回收,即保证退出步骤的执行。其用处最多的是,作为确保资源被正确回收的一种方式。
一种重复使用的 try-except-finally
结构的有效机制,因为其功能是封闭代码,且可以填充任意格式的代码块。
语法上 __enter__
不接受其余参数,除了自带的self
之外,__exit__
在不包括self参数外,还包括三个参数(一个异常类型,一个异常实例和一个回溯),即exc_type
,exc_instance
,traceback
,默认设置为None
可以通过让一个__exit__
方法返回False
实现异常传播,或者返回True
终止异常。如果抛出另一个异常,将会代码原本的异常被发出去。
编写上下文的场景
- 资源清理,例如打开数据库,打开文件等需要被正确关闭的资源
- 避免重复
1.传播异常
2.终止异常
3.处理特定异常类(实例4)
4.不包括的子类(实例5)
原则1:简单的终止所有异常与try-except
语句相同,但终止过多的错误会造成代码调试困难,一些隐含错误也会错误,造成过多的不确性。
代码讲解
实例1
# coding: utf-8
class ContextManager(object):
def __init__(self):
self.entered = False
def __enter__(self):
self.entered = True
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.entered = False
cm = ContextManager() # 实例化一个对象,如果在其余地方不使用实例对象
# 写成 with ContextManager() as cm:
with cm:
print(cm.entered) # enter 方法返回对象,在 enter 作用范围内 self.enter 为 True
print(cm.entered) # 执行了 exit 方法,返回的是 False
实例2
__exit__
能处理异常,代码内引起的异常首先传给了__exit__
并得到了正常的处理,返回False
即异常被重新抛出给主模块,返回True
则终止了异常在__exit__
方法内
# coding: utf-8
class BubbleExceptions(object):
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_val:
print("Bubbing up exception: {}".format(exc_val))
return True
with BubbleExceptions():
print(5/0)
"""
__exit__ 返回 False
Bubbing up exception: division by zero
Traceback (most recent call last):
File "/home/yuge/Documents/book/test.py", line 15, in <module>
print(5/0)
ZeroDivisionError: division by zero
__exit__ 返回True
Bubbing up exception: division by zero
"""
实例3: 上下文内被正常处理的异常,不会发给__exit__
# coding: utf-8
class BubbleExceptions(object):
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_val:
print("Bubbing up exception: {}".format(exc_val))
return False
with BubbleExceptions():
try:
print(5/0)
except ZeroDivisionError:
print("这是一个错误!")
"""
运行结果:
这是一个错误!
"""
实例4:__exit__
可以处理特定异常类
即在__exit__
方法里封装代码,将处理特定异常类的代码放进去,有点像try-except
一样,最多的不同是,其代码可以重用。
# 处理特定的异常,并根据是否提起了其他异常类来决定是否返回 True 或 False
# coding: utf-8
class HandleValueError(object):
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if not exc_type:
# 即没有异常出现
return True
if issubclass(exc_type, ValueError):
print("捕捉到了一个 ValueError:{}".format(exc_val))
return True
return False
with HandleValueError():
# raise ValueError("错误的值!")
raise TypeError("错误的类型!")
"""
raise ValueError("错误的值!")
捕捉到了一个 ValueError:错误的值!
raise TypeError("错误的类型!")
Traceback (most recent call last):
File "/home/yuge/Documents/book/test.py", line 22, in <module>
raise TypeError("错误的类型!")
TypeError: 错误的类型!
"""
实例5:如何处理特定的类,不处理其子类
# coding: utf-8
class ValueErrorSubclass(ValueError):
pass
class HandleValueError(object):
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if not exc_type:
return True
# 这里只处理 ValueError 的错误,即不处理基类的子类
if exc_type == ValueError:
print("处理了一个 ValueError 的错误:{}".format(exc_val))
return True
# if issubclass(exc_type, ValueError):
# # 这里处理了包括 基类的 所有类集体
# print("处理了基于 ValueError 的错误:{}".format(exc_val))
# return True
return False
with HandleValueError():
raise ValueErrorSubclass("这就是个失误")
"""
包括 issubclass
处理了基于 ValueError 的错误:这就是个失误
注释了 issubclass 之后
Traceback (most recent call last):
File "/home/yuge/Documents/book/test.py", line 30, in <module>
raise ValueErrorSubclass("这就是个失误")
__main__.ValueErrorSubclass: 这就是个失误
"""
python之简述上下文管理的更多相关文章
- python with语句上下文管理的两种实现方法
在编程中会经常碰到这种情况:有一个特殊的语句块,在执行这个语句块之前需要先执行一些准备动作:当语句块执行完成后,需要继续执行一些收尾动作.例如,文件读写后需要关闭,数据库读写完毕需要关闭连接,资源的加 ...
- (转)Python中的上下文管理器和Tornado对其的巧妙应用
原文:https://www.binss.me/blog/the-context-manager-of-python-and-the-applications-in-tornado/ 上下文是什么? ...
- Python之面向对象上下文管理协议
Python之面向对象上下文管理协议 析构函数: import time class Open: def __init__(self,filepath,mode='r',encode='utf-8') ...
- Python深入02 上下文管理器
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 上下文管理器(context manager)是Python2.5开始支持的一种语 ...
- Python中的上下文管理器和with语句
Python2.5之后引入了上下文管理器(context manager),算是Python的黑魔法之一,它用于规定某个对象的使用范围.本文是针对于该功能的思考总结. 为什么需要上下文管理器? 首先, ...
- 深入理解 Python 中的上下文管理器
提示:前面的内容较为基础,重点知识在后半段. with 这个关键字,对于每一学习Python的人,都不会陌生. 操作文本对象的时候,几乎所有的人都会让我们要用 with open ,这就是一个上下文管 ...
- 【Python】【上下文管理器】
"""#[备注]#1⃣️try :仅当try块中没有异常抛出时才运行else块.#2⃣️for:仅当for循环运行完毕(即for循环没有被break语句终止)才运行els ...
- python中实现上下文管理器的两种方法
上下文管理器: python中实现了__enter__和__exit__方法的对象就可以称之为上下文管理器 实现方法一举例: def File(object): def __init__(self, ...
- python 描述符 上下文管理协议 类装饰器 property metaclass
1.描述符 #!/usr/bin/python env # coding=utf-8 # 数据描述符__get__ __set__ __delete__ ''' 描述符总结 描述符是可以实现大部分py ...
随机推荐
- [Javascript] Getter and Setter Abstractions
JavaScript provides primitive types and means of processing those. However, those are not enough. Re ...
- ntp服务及时间同步问题
今有一小型项目,全然自主弄,原来以为非常easy的NTP服务.我给折腾了2个多小时才整撑头(曾经都是运维搞,没太注意,所以这技术的东西.在简单都须要亲尝啊).这里记录为以后别再浪费时间. 目标环境,5 ...
- linux命令之man和info
linux命令之man和info man ➜ ~ man ls result: LS(1)中1这样的数字的意义例如以下所看到的: 代号 内容 1 用户在shell环境中能够操作的命令或可运行文件 2 ...
- luogu4012 深海机器人问题 网络流
关键词:最小费用最大流 题目大意:海底是个网格,每个网格边有一定价值的海底化石.每个路线可经过无限个机器人,但上面的化石只能采一次.机器人可沿网格边向东或向北移动.给定机器人起点和终点位置及所能容纳的 ...
- Node.js:目录
ylbtech-Node.js:目录 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 1. http://www.runoob.com/nodejs/nodejs ...
- [xPlugin] smartupload jsp图片上传
URL:http://www.cnblogs.com/ISeeYouBlogs/p/jsp.html 1.要实现图片上传,首先需要一个组件,这里我用的是smartupload.jar可以到这里下载ht ...
- WinForm导出DataSet到Excel
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- let,const,var三者之间的区别
在ES6中新增了两种定义变量的命令let和const,在这之前相信大家都对var定义变量很熟悉,那么在了解ES6方法前, 1.我们先来回顾一下var定义变量的方法. 下面来看这段代码: for (va ...
- tab选项卡切换(js原生、jQuery )
思路: ① 遍历Tab选项 ② 然后给每个Tab选项绑定点击事件 ③ 每次点击时清除所有Tab选项及Tab选项内容的样式,然后给当前Tab选项添加标记样式,给当前Tab选项添加显示样式 <!DO ...
- HTTP获取信息的四种方式
HTTP 从网络获取信息的四种方式 GET GET指代你在浏览器中输入网址,浏览网站时做的事.例如,我们使用 http://www.baidu.com 的时候,可以将GET想象成他说:"hi ...