python - open 如何处理上下文管理?

标签 python file with-statement contextmanager

Python 内置函数 openfile 以我不太理解的方式与上下文管理器一起工作。

据我了解,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/

相关文章:

java - 即使单元格具有值,cellIterator.hasNext() 也会返回 false

delphi - 重构 "with" block 的工具

python - 在上下文管理器 __enter__() 中捕获异常

python - 如何将 NumPy 特征和标签数组转换为可用于 model.fit() 的 TensorFlow 数据集?

python - Matplotlib 不同颜色的刻度线和标签

asp.net-mvc - 支持从 asp.net mvc 站点托管文件的安全方法

Python:文件读取器 int 和 if 子句

python - Tkinter 框架调整一轴大小

python - 具有长度的对象的类型

python - 使用可变数量的上下文管理器替代 contextlib.nested