我对如何安排Python上下文管理器可以做的所有事情感到困惑。
据我所知,构建上下文管理器的潜在元素包括:
A:总是发生的事情 B:C所需的某些准备工作 C:创建和建立在上下文中使用的对象X D:在上下文开始之前使用成功建立的X执行一些事情 E:将X返回到上下文(用于由
我想我大致明白每个元素在上下文管理器函数中的位置,但完全不知道如何在类中排列它们。
是否有一个上下文管理器函数和类的模板,显示了这些元素在函数和(特别是)类中的位置?我查看了许多此处和其他地方的示例,但没有找到综合的示例,而且许多示例使用实际代码,我无法总结出每个上述元素的含义。
我认为当通过函数实现时,我基本上理解上下文管理器的行为。
例如,如果要打开一个文件,并在成功打开和关闭时向其写入内容,但如果出现问题,则需要清理该文件,可以编写以下代码:
据我所知,构建上下文管理器的潜在元素包括:
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