Python 内置函数 open
和 file
以我不太理解的方式与上下文管理器一起工作。
据我了解,open
将创建一个文件
。 file
实现上下文管理器方法 __enter__
和 __exit__
。我最初希望 __enter__
实现文件描述符的实际打开。
但是,在 with
block 之外使用 open
将返回一个已打开的file
。因此,看起来 file.__init__
或 open
实际上正在打开文件描述符,据我所知 file.__enter__
不是。什么都不做。或者file.__init__
/open
直接调用file.__enter__
?
第一个问题:
内置open
的执行流程是怎样的? open
处理什么,file.__init__
处理什么,file.__enter__
处理什么?当重复使用一个 file
对象来多次打开/关闭文件时,这是如何工作的?这与在多个上下文循环中重复使用其他 contextmanager 对象有何不同?
第二个问题:
诸如file
对象之类的对象具有设置步骤和拆卸步骤。设置发生在 __init__
中,拆卸发生在 close
或 __exit__
中。
这是一个好的设计模式吗?是否应该为自定义功能/上下文管理器实现此设计模式?
最佳答案
如果查看 _pyio.py(io 模块的纯 Python 实现),您会在 IOBase 类中找到以下代码:
### Context manager ###
def __enter__(self): # That's a forward reference
"""Context management protocol. Returns self (an instance of IOBase)."""
self._checkClosed()
return self
def __exit__(self, *args):
"""Context management protocol. Calls close()"""
self.close()
这包含您大部分问题的答案。需要理解的重要一点是,上下文管理器的功能是确保您在使用完文件后将其关闭。它只需调用 close
函数即可完成此操作,从而省去了您这样做的麻烦。
file.__enter__
处理什么?没有什么。它只是将文件对象返回给您,该文件对象是调用内置函数 open() 的结果。
当使用一个文件对象多次打开和关闭文件时,这是如何工作的?上下文管理器对于此目的不是很有用,因为您每次都必须显式打开文件。
这是一个好的设计模式吗?是的,因为它减少了您必须编写的代码量,所以很容易阅读和理解。
是否应该为自定义函数/上下文管理器实现此模式?任何时候你有一个对象需要清理,或者使用涉及某种类型的打开/关闭概念,你应该考虑这种模式。标准库还有许多其他示例。
关于python - open 如何处理上下文管理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49122128/