【发布时间】:2021-10-22 00:35:18
【问题描述】:
我最近一直在研究 Python 的 contextmanager(更具体地说,是 Python 3 的 contextlib 或其反向移植的 contextlib2),我想知道将它们编写为类与函数的优点/缺点是什么?
它们似乎都以相同的方式运行并以相同的方式处理异常。有很多很酷的实用程序,例如 ExitStack(),但这些实用程序似乎可以在编写为类或函数的上下文管理器中实现。因此,我正在努力寻找一个很好的理由来解释为什么人们想要将上下文管理器详细地编写为一个类,而它们可以被编写为一个函数并且只是在 contextmanager 装饰器上打一巴掌。
这是我写的一个简单的例子来展示两者做同样的事情:
# !/usr/bin/python -u
# encoding: utf-8
from contextlib import contextmanager
# Function-based
@contextmanager
def func_custom_open(filename, mode):
try:
f = open(filename, mode)
yield f
except Exception as e:
print(e)
finally:
f.close()
# Class-based
class class_custom_open(object):
def __init__(self, filename, mode):
self.f = open(filename, mode)
def __enter__(self):
return self.f
def __exit__(self, type, value, traceback):
self.f.close()
if __name__ == '__main__':
# Function-based
with func_custom_open('holafile_func.txt', 'w') as func_f:
func_f.write('hola func!')
# Class-based
with class_custom_open('holafile_class.txt', 'w') as class_f:
class_f.write('hola class!')
【问题讨论】:
-
如果你想让你的上下文管理器成为除了上下文管理器之外的任何东西,你不能使用
@contextmanager。
标签: python function class contextmanager