我对如何将 Python 上下文管理器可以做的所有事情安排到适当的位置感到困惑。
据我了解,可能用于构建上下文管理器的元素包括:
- A:总会发生的事情
- B: C需要一些准备
- C:创建并建立上下文中使用的对象 X
- D:在上下文开始之前使用成功建立的 X 做一些事情
- E:将 X 返回到上下文(供 使用
as
) - F:在上下文结束时一切顺利时用 X 结束
- G:在进入上下文之前处理 C 和 B 失败的后果
- H:在上下文中处理失败的后果
我想我大致了解了每个元素在上下文管理器函数中的位置,但是对于如何在类中安排它们完全不知所措。
是否有上下文管理器函数和类的模板来显示这些元素中的每一个是否同时出现在函数和(尤其是)类中?我在这里和其他地方查看了许多示例,但没有发现一个全面的示例,而且许多示例使用了我无法始终映射到上面每个构建块的实际代码。
我想我基本上了解上下文管理器在通过函数实现时的行为方式:
from contextlib import contextmanager
@contextmanager
def log_file_open(oec_data, build_description, log_dir):
# A: Something that always happens
try:
# B: Some stuff needed to make a_thing
a_thing = establish_thing_in_a_way_that_might_fail() # C
# D: Some things that happen using a_thing at context start
yield a_thing # E
# F: Wrap up with a_thing when all is well
except:
# G: Deal the consequences of failure in try or...
# H: Deal the consequences of failure in context
finally:
# Could F go here instead?
例如,要打开一个文件,该文件应该在成功打开和关闭时写入,但如果出现问题应该清理,我可以写
from contextlib import contextmanager
@contextmanager
def log_file_open(oec_data, build_description, log_dir):
print('Entering context...')
try:
usable_file_name = get_some_name()
a_thing = open(usable_file_name, mode='w')
a_thing.write('Logging context started.')
yield a_thing
a_thing.write('Logging context ended.')
except:
a_thing.close()
os.remove(a_thing.name)
raise
但我不确定这是对的,我很困惑它如何映射到类的使用__enter()__
和__exit()__
类中。是(示意性地):
def __init__(self):
# A: Something that always happens
def __enter__(self):
try:
# B: Some stuff needed to make a_thing
a_thing = establish_thing_in_a_way_that_might_fail() # C
# D: Some things that happen using a_thing at context start
except:
# G: Deal the consequences of failure in try
a_thing = some_appropriate_blank_value
finally:
return a_thing # E
def __exit__(self, type, value, traceback):
if type is None:
# F: Wrap up with a_thing when all is well
return True
else:
# H: Deal the consequences of failure in context
return False