【Python】with语句的执行原理
with语句
- with 语句是 Pyhton 提供的一种简化语法,with 语句是从 Python 2.5 开始引入的一种与异常处理相关的功能。
- with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源。
- 比如文件使用后自动关闭、数据库的打开和自动关闭等。,with 语句在编写代码时,会使代码变得更加简洁。
with语句的执行原理
- with 语句在执行时,需要调用上下文管理器中的__enter__和__exit__两个方法。
- __enter__方法会在执行 with 后面的语句时执行,一般用来处理操作前的内容。比如一些创建对象,初始化等。
- __exit__方法会在 with 内的代码执行完毕后执行,一般用来处理一些善后收尾工作,比如文件的关闭,数据库的关闭等。
自定义一个上下文管理器
import time
class MyOpen(object):
# file:文件名, mode:打开方式
def __init__(self,file, mode):
self.__file = file
self.__mode = mode
def __enter__(self):
print('__enter__ run ... 打开文件')
self.__handle = open(self.__file, self.__mode)
return self.__handle
def __exit__(self, exc_type, exc_val, exc_tb):
print('__exit__ run ... 关闭文件')
self.__handle.close()
with MyOpen('test','w') as f:
f.write('自定义上下文管理器')
# 为了展示效果,等待3秒后再执行__exit__
time.sleep(3)
# 执行效果
__enter__ run ... 打开文件
(这里会停顿3秒)
__exit__ run ... 关闭文件
__exit__方法的参数
__exit__方法中有三个参数,用来接收处理异常,如果代码在运行时发生异常,异常会被保存到这里。
- exc_type : 异常类型
- exc_val : 异常值
- exc_tb : 异常回溯追踪
自定义__exit__的异常处理
定义一个两数相除的类
class MyCount(object):
def __init__(self, x, y):
self.__x = x
self.__y = y
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
# 通过 参数接收到的值,来判断程序执行是否出现异常
# 如果是 None ,说明没有异常
if exc_type == None:
print('计算正确执行')
else:
# 否则出现异常,可以选择怎么处理异常
print('程序有异常哦(除数不能为0)')
# 返回值如果是 False 那么就会继续向外抛出,程序会看到系统提示的异常信息
# 返回值如果是 True 不会向外抛出,程序看不到系统提示信息,只能看到else中的输出
return False
def div(self):
print(self.__x / self.__y)
# 这里与文件处理语法相同:with open('test', 'w') as f:
# 做6÷0运算
with MyCount(6, 0) as mc:
mc.div()
返回值为False,执行效果:
将异常信息抛出,用户体验不好
将返回值改为True,运行效果:
并没有抛出异常信息,只抛出了我们自定义的异常信息。
总结
- with语句主要是为了简化代码操作。
- with在执行过程中,会自动调用上下文管理器中的__enter__和__exit__方法
- __enter__方法主要用来做一些准备操作
- __exit__方法主要用来做一些善后工作