Bee*_*ope 2 python contextmanager
我找到了下面的例子以下对象上下文管理器的File:
class File(object):\n def __init__(self, file_name, method):\n self.file_obj = open(file_name, method)\n def __enter__(self):\n return self.file_obj\n def __exit__(self, type, value, traceback):\n self.file_obj.close()\nRun Code Online (Sandbox Code Playgroud)\n在这里,管理器完成的工作(实际上是打开文件)发生在该__init__方法中。然而,在随附的文本中,他们建议文件打开应该发生在__enter__:
\n\n让\xe2\x80\x99s 谈谈幕后发生的事情。
\n\n
\n- with 语句存储退出File类的
\n- 它调用输入File 类的
\n- 进入打开文件并返回它。
\n- 打开的文件句柄被传递给opened_file。
\n- 我们使用 .write() 写入文件。
\n- with 语句调用存储的退出方法。
\n- 出口关闭文件。
\n
一般来说,哪种方法是正确的?似乎撤销的工作__exit__应该发生在__enter__,而不是__init__因为它们是通过上下文管理器机制 1:1 配对的,但这个例子让我感到怀疑。
没有一般性的答案。这取决于工作是什么。例如,对于文件,打开发生在__init__,但对于锁,锁定发生在__enter__。
需要考虑的一件重要事情是,如果对象不用作上下文管理器,或者不立即用作上下文管理器,会发生什么情况?构建后对象的状态应该是什么?那时是否应该已经获得相关资源?
对于文件,答案是肯定的,该文件应该已经打开,因此打开发生在__init__. 对于锁来说,答案是否定的,锁不应该被锁,所以锁就进去了__enter__。
另一件需要考虑的事情是,这个对象是否可以多次用作上下文管理器?如果进入上下文管理器两次应该做两次某件事,那么该事情需要在__enter__.