Python中with用法详解
一 、with语句的原理
- 上下文管理协议(Context Management Protocol):包含方法
__enter__()和__exit__(),支持该协议的对象要实现这两个方法。 - 上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了
__enter__()和__exit__()方法。上下文管理器定义执行with语句时要建立的运行时上下文,负责执行with语句块上下文中的进入与退出操作。通常使用with语句调用上下文管理器,也可以通过直接调用其方法来使用。
说完上面两个概念,我们再从with语句的常用表达式入手,一段基本的with表达式,其结构是这样的:
with EXPR as VAR:
BLOCK
其中EXPR可以是任意表达式;as VAR是可选的。其一般的执行过程是这样的:
- 执行EXPR,生成上下文管理器context_manager;
- 获取上下文管理器的
__exit()__方法,并保存起来用于之后的调用; - 调用上下文管理器的
__enter__()方法;如果使用了as子句,则将__enter__()方法的返回值赋值给as子句中的VAR; - 执行BLOCK中的表达式;
- 不管是否执行过程中是否发生了异常,执行上下文管理器的
__exit__()方法,__exit__()方法负责执行“清理”工作,如释放资源等。如果执行过程中没有出现异常,或者语句体中执行了语句break/continue/return,则以None作为参数调用__exit__(None, None, None);如果执行过程中出现异常,则使用sys.exc_info得到的异常信息为参数调用__exit__(exc_type, exc_value, exc_traceback); - 出现异常时,如果
__exit__(type, value, traceback)返回False,则会重新抛出异常,让with之外的语句逻辑来处理异常,这也是通用做法;如果返回True,则忽略异常,不再对异常进行处理。
二、自定义上下文管理器
Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。
# coding = utf-8
# 2019/7/19 Luckyxxt:有趣的事,Python永远不会缺席!
#!/usr/bin/env python class DBManager(object):
def __init__(self):
pass def __enter__(self):
print('__enter__')
return self def __exit__(self, exc_type, exc_val, exc_tb):
print('__exit__')
return True def getInstance():
return DBManager() with getInstance() as dbManagerIns:
print('with demo')
with后面必须跟一个上下文管理器,如果使用了as,则是把上下文管理器的 __enter__() 方法的返回值赋值给 target,target 可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)
代码运行结果如下:
'''
__enter__
with demo
__exit__ '''
结果分析:当我们使用with的时候,__enter__方法被调用,并且将返回值赋值给as后面的变量,并且在退出with的时候自动执行__exit__方法
class With_work(object):
def __enter__(self):
"""进入with语句的时候被调用"""
print('enter called')
return "xxt" def __exit__(self, exc_type, exc_val, exc_tb):
"""离开with的时候被with调用"""
print('exit called') with With_work() as f:
print(f)
print('hello with')
'''
enter called
xxt
hello with
exit called '''
三、总结
自定义上下文管理器来对软件系统中的资源进行管理,比如数据库连接、共享资源的访问控制等。
Python中with用法详解的更多相关文章
- Python中enumerate用法详解
enumerate()是python的内置函数.适用于python2.x和python3.xenumerate在字典上是枚举.列举的意思enumerate参数为可遍历/可迭代的对象(如列表.字符串)e ...
- python中threading模块详解(一)
python中threading模块详解(一) 来源 http://blog.chinaunix.net/uid-27571599-id-3484048.html threading提供了一个比thr ...
- python操作redis用法详解
python操作redis用法详解 转载地址 1.redis连接 redis提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用 ...
- python的requests用法详解
Requests是一个Python语言写的http相关设置或者请求的一个库 安装:pip install Requests或者pip3 install requests 使用的时候要import re ...
- AngularJS select中ngOptions用法详解
AngularJS select中ngOptions用法详解 一.用法 ngOption针对不同类型的数据源有不同的用法,主要体现在数组和对象上. 数组: label for value in a ...
- Python中time模块详解
Python中time模块详解 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. ...
- C++中的STL中map用法详解(转)
原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解 Map是STL的一个关联容器,它提供 ...
- 第7.19节 Python中的抽象类详解:abstractmethod、abc与真实子类
第7.19节 Python中的抽象类详解:abstractmethod.abc与真实子类 一. 引言 前面相关的章节已经介绍过,Python中定义某种类型是以实现了该类型对应的协议为标准的,而不 ...
- 76.Python中F表达式详解
F表达式是用来优化ORM操作数据库的. 举个例子:我们做口罩的公司要将所有员工的薪水增加2000元,如果按照正常的流程,应该是先从数据库中提取所有的员工的工资到Python内存中,然后使用Python ...
随机推荐
- 008-SpringBoot发布WAR启动报错:Error assembling WAR: webxml attribute is required
一.Spring Boot发布war包流程: 1.修改web model的pom.xml <packaging>war</packaging> SpringBoot默认发布的都 ...
- 品优购商城项目(二)AngularJS、自动代码生成器、select2下拉多选框
品优购商城想项目第二阶段 AngularJS.自动代码生成器.select2下拉多选框 完成了课程第三天.第四天的的任务. 1.学习了AngularJs前端的mvc分层思想,js部分分成control ...
- 泡泡一分钟:Perception-aware Receding Horizon Navigation for MAVs
作为在空中抛掷四旋翼飞行器后恢复的第一步,它需要检测它使用其加速度计的发射.理想的情况下,在飞行中,加速度计理想地仅测量由于施加的转子推力引起的加速度,即.因此,当四旋翼飞行器发射时,我们可以检测到测 ...
- 如何把VMware Workstation使用的虚拟SCSI磁盘转换成虚拟IDE硬盘
如何把VMware Workstation使用的虚拟SCSI磁盘转换成虚拟IDE硬盘 摘自:http://blog.sina.com.cn/s/blog_7525b71f0101d0u8.html ...
- Qt编写自定义控件67-通用无边框
一.前言 在之前的一篇文章中写过一个通用的移动控件,作用就是用来传入任意的widget控件,可以在父类容器中自由移动.本篇文章要写的是一个通用的无边框类,确切的说这不叫控件应该叫组件才对,控件是要看得 ...
- php cURL error 60: SSL certificate problem: unable to get local issuer certificate 解决办法
错误例子如下: php5.6以上的版本会出现这种问题 关于“SSL证书问题:无法获取本地颁发者证书”错误.很明显,这适用于发送CURL请求的系统(并且没有服务器接收请求) 1)从https://cur ...
- AI佳作解读系列(六) - 生成对抗网络(GAN)综述精华
注:本文来自机器之心的PaperWeekly系列:万字综述之生成对抗网络(GAN),如有侵权,请联系删除,谢谢! 前阵子学习 GAN 的过程发现现在的 GAN 综述文章大都是 2016 年 Ian G ...
- jmeter的安装教程
JMETER安装教程 jmeter的安装教程 1:安装jdk并且配置好环境变量,此处就不做赘述(前面的文档中有) 2:下载jmeter文件和jmeter的插件文件 JMeter:http://jmet ...
- C# Hook原理及EasyHook
C# Hook原理及EasyHook简易教程 前言 在说C# Hook之前,我们先来说说什么是Hook技术.相信大家都接触过外挂,不管是修改游戏客户端的也好,盗取密码的也罢,它们都是如何实现的呢? 实 ...
- Redis持久化RDB、AOF
持久化的意思就是保存,保存到硬盘.第一次接触这个词是在几年前学习EF. 为什么要持久化 redis定义:Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代 ...