python中with的具体用法
作者:youhebuke225 发布时间:2021-12-08 17:41:16
简介
with的基本表达式如下
with context_expression [as target(s)]:
...
with-body
其中context_expression 可以是任意的表达式,as target(s)是可选的
他的执行过程如下
context_manager = context_expression
exit = type(context_manager).__exit__
value = type(context_manager).__enter__(context_manager)
exc = True # True 表示正常执行,即便有异常也忽略;False 表示重新抛出异常,需要对异常进行处理
try:
try:
target = value # 如果使用了 as 子句
with-body # 执行 with-body
except:
# 执行过程中有异常发生
exc = False
# 如果 __exit__ 返回 True,则异常被忽略;如果返回 False,则重新抛出异常
# 由外层代码对异常进行处理
if not exit(context_manager, *sys.exc_info()):
raise
finally:
# 正常退出,或者通过 statement-body 中的 break/continue/return 语句退出
# 或者忽略异常退出
if exc:
exit(context_manager, None, None, None)
# 缺省返回 None,None 在布尔上下文中看做是 False
深入
首先我们来了解两个概念,上下文管理对象与上下文协议
上下文管理器:支持上下文管理协议的对象,这里我们就要知道什么是上下文管理管理协议了,请看第二点。上下文管理器运行with语句是要建立运行的上下文,负责执行with语句块上下文中的进入与退出操作。
上下文管理协议:包含方法__enter__()和__exit__(),支持协议的对象要实现这两个方法
理解完上面的两点,我们就很容易知道with语句的执行流程,我们看着上面的执行过程代码来看
执行context_expression ,生成山下文管理器context_manager
调用上下文管理器的__enter__方法,这个时候如果使用了as,那么就会将__enter__方法的返回值赋值给target
执行with-body
不管执行过程中是否发生了异常都会执行上下文管理器的__exit__方法,它用于负责执行清理工作,如释放资源等。
如果执行过程中没有出现异常,或者语句中执行了语句break/continue/return,则以None作为参数调用__exit__(None,None,None);如果执行过程中出现了异常,则使用sys.excinfo得到异常信息作为参数调用__exit__(exc_type,exc_value,exc_traceback)
出现异常时,如果__exit__(exc_type,exc_value,exc_traceback)返回false,则会重新抛出异常,让with完的语句来处理异常,如果__exit__(exc_type,exc_value,exc_traceback)返回True,则异常忽略,不在对于异常来进行处理
代码
没有报错
class Test:
def __enter__(self):
print("__enter__")
return "hello python"
def __exit__(self, type, value, trace):
print("__exit__")
pass
def get_test():
return Test()
with get_test() as test:
print(test)
他的打印如下
__enter__
hello python
__exit__
有报错
class Test:
def __enter__(self):
print("__enter__")
return "hello python"
def __exit__(self, type, value, trace):
print("type", type)
print("value", value)
print("trace", trace)
print("__exit__")
def get_test():
return Test()
with get_test() as test:
print(test)
1 / 0
打印如下
hello python
type <class 'ZeroDivisionError'>
value division by zero
trace <traceback object at 0x0000024938B07B40>
__exit__
Traceback (most recent call last):
File "f:/my_profile/study/code_pub/study_code_pub/python/关键字/with.py", line 35, in <module>
1 / 0
可以看出来当有报错的时候,他是抛出了异常,因为__exit__没有返回值,当他返回True的时候,他的打印如下
当__exit__返回True时
__enter__
hello python
type <class 'ZeroDivisionError'>
value division by zero
trace <traceback object at 0x000001FB117885C0>
__exit__
我们会发现他没有了报错信息
来源:https://blog.csdn.net/youhebuke225/article/details/129098821
猜你喜欢
- Oracle游标分为显示游标和隐式游标。显示游标(Explicit Cursor):在PL/SQL程序中定义的、用于查询的游标称作显示游标。
- 思路:遍历文件夹下面的文件夹如果文件夹名称等于".svn",则修改文件夹的属性(因为".svn"的文
- 使用 pyecharts 渲染成图片一直是开发者比较关心的功能,pyecharts提供了 selenium、phantomjs 和 pypp
- 很多查询类的存储过程会返回一个表结构的结果集,如果在其他存储过程中需要用到这个结果集,为了避免编写重复的sql脚本,可以直接使用前者的查询结
- 1. 首先确认python的版本为2.3.4以上,如果不是需要升级python的版本 python -V
- <HTML> <BODY> <
- 一、意义:当我们使用一个数据库时,总希望数据库的内容是可靠的、正确的,但由于计算机系统的故障(硬件故障、网络故障、进程故障和系统故障)影响数
- root账户为MySQL的超级管理员用户,拥有MySQL提供的所有权限。我们登录了root账户可以重置其它创建的所有用户的密码,那么root
- 在python中,可以把for循环写在一行,生成一个新的列表,使用起来非常方便,下面举几个简单例子体会一下。1.简单的for...[if].
- 之前用bash实现过(https://www.jb51.net/article/61943.htm),不过那个不能在windows下使用,所
- 由于CPython实现中的GIL的限制,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大
- python 3.x 环境下,使用h5py加载HDF5文件,查看keys,如下:>>> import h5py>&g
- 先来看一个概念:数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完整地执行,要么完全
- 官网地址:https://www.mysql.com/安装建议:尽量不要用.exe进行安装,用压缩包安装,对日后的卸载更为方便下载地址:ht
- 一、相关配置如下 操作系统: CentOS 7.2 &nb
- 前言操作符是数据库具有的运算特性,对文本字符和一些标签字符的处理,使用操作符可以简化SQL代码,同时也可以节省开发时间和提高开发效率。比较操
- 这是一篇知识性的文档,主要目的是为了让Web缓存相关概念更容易被开发者理解并应用于实际的应用环境中。为了简要起见,某些实现方面的细节被简化或
- DiscoArt 是一个很牛的开源模块,它能根据你给定的关键词自动绘画。绘制过程是完全可见的,你可以在 jupyter 页面上看见这个绘制的
- 1.创建带有缺失值的数据库:import pandas as pdimport numpy as npdf = pd.DataFrame(n
- 1. 稀疏矩阵的建立:coo_matrix()from scipy.sparse import coo_matrix# 建立稀疏矩阵data