文章目录
1 上下文管理
文件IO操作可以对文件对象使用上下文管理,它主要使用with..as..
语法.
with open('123.txt') as f:
print(f)
要想自己写的类实现上下文管理,那么需要用到两个方法__exit__和__enter__.
方法 | 意义 |
---|---|
__enter__ | 进入与此对象相关的上下文,如果存放该方法,with语法会把该方法的返回值绑定到as子句中指定的变量上 |
__exit__ | 退出与此对象相关的上下文 |
class Text:
def __enter__(self):
print('enter------')
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit-------')
with Text() as f :
print('进来了')
print('出来了')
# enter------
# 进来了
# exit-------
# 出来了
实例化对象的时候,并不会调用__enter__方法,只有进入with语句体中,才会调用__enter__方法,然后执行语句体,最后离开with语句块的时候,再调用__exit__方法.
with可以开启一个上下文运行环境,在执行前做一些准备工作,执行后,做一些收尾工作,它并不会开启一个新的作用域.
1.1 上下文管理的安全性
class Text:
def __enter__(self):
print('enter------')
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit-------')
with Text() as f :
raise Exception
# Traceback (most recent call last):
# enter------
# File "E:/Python - base - code/chapter08面向对象/练习3.py", line 169, in <module>
# raise Exception
# exit-------
# Exception
我们可以看到,with语句体中当异常抛出时,__exit__已经可以执行完毕,所以上下文管理是安全的.
1.2 返回值
class Text:
def __enter__(self):
print('enter------')
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit-------')
with Text() as f :
print(f) # None
这里之所以是None,是因为,__enter__函数的返回值为None,所以如果哪些类的实例化属性或实例本身要在with语句内部使用,可以在__enter__函数中进行返回.
class Text:
def __init__(self):
self.name = 'daxin'
def __enter__(self):
print('enter------')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit-------')
with Text() as f:
print(f.name) # daxin
1.3 方法的参数
方法的参数如下:
- __enter__(self):没有其他参数
- __exit__(self, exc_type, exc_val, exc_tb): 这三个参数都与异常有关系,如果上下文管理内部没有产生异常,那么三个属性的值都为None,否则
- exc_type: 异常类型
- exc_val: 异常的值
- exc_tb: 异常的追踪信息
注意:__exit__函数的返回值很重要,当返回值等效为True,表示压制异常(异常不会上报),等效False时,表示不压制异常(此时异常会上报)
class A:
def __init__(self):
pass
def __enter__(self):
print('Enter ~~~~~')
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit ~~~~~')
print(exc_type)
print(exc_val)
print(exc_tb)
return True