上下文管理器与with语句
class A:
def __enter__(self):
a = 1
def __exit__(self):
b = 2
with A() as obj_A:
pass
思考:此时的obj_A指向的是什么?
答:指像的是None, obj_A指向的不是上下文管理器,而是__enter__
方法的返回值,此时没有返回值。因此obj_A指向的是None。如何让其指向不为None?
注:以下示例代码只能用于debug模式查看obj_A的指向状态,由于__exit__
方法没有实现完成会报错。
class A:
def __enter__(self):
a = 1
return a
def __exit__(self):
b = 2
with A() as obj_A:
pass
关于__exit__
方法的下一步说明:
__exit__
方法需要接收4个参数,在执行过程中如果发生了异常将不会继续执行而直接执行__exit__
方法,而__exit__
方法中的参数则代表对异常的描述。exc_type代表异常类型,exc_val代表异常值,tb代表traceback的缩写:返回错误地址。
class Context(object):
def __enter__(self):
print('-------- 连接到资源 ------- ')
return self
def func_A(self):
print("——————正在执行方法A————————")
def __exit__(self, exc_type, exc_val, exc_tb):
print('———————— 释放资源 —————————')
with Context() as C:
C.func_A()
-
__exit__
异常处理__exit__
方法返回值只有两种(True or False)。外部没有抛出异常的情况:
class Context(object):
def __enter__(self):
print('-------- 连接到资源 ------- ')
return self
def func_A(self):
print("——————正在执行方法A————————")
def __exit__(self, exc_type, exc_val, exc_tb):
print('———————— 释放资源 —————————')
return True
with Context() as C:
a = 1/0
C.func_A()
# 执行结果:没有抛出异常
-------- 连接到资源 -------
———————— 释放资源 —————————
Process finished with exit code 0
外部抛出异常(__exit__
方法无返回值时默认以False处理):
class Context(object):
def __enter__(self):
print('-------- 连接到资源 ------- ')
return self
def func_A(self):
print("——————正在执行方法A————————")
def __exit__(self, exc_type, exc_val, exc_tb):
print('———————— 释放资源 —————————')
return False
try:
with Context() as C:
a = 1/0
C.func_A()
except Exception as Ex:
print("出现错误:",Ex)
# 执行结果: