python - 我应该关闭在上下文管理器 __exit__() 函数中传递到我的对象的流(类文件对象)吗?

标签 python file stream contextmanager

我有一个对象,我希望能够在该对象上使用 with 关键字。我对实现上下文管理器的实用性感到满意,但我正在努力解决最佳实践问题。

该对象是文件的包装器。我计划用一个字符串(文件的路径)或一个可以直接处理的类似文件来初始化我的对象(文件中有文件的可能性 - 所以我预见到一个明确的用例这与 BytesIO 等......)

所以 __init__ 看起来像这样:

def __init__(self, file_to_process):
    if isinstance(file_to_process, str):
        self._underlying_stream = open(file_to_process, "rb") # it's the path to a file
    elif isinstance(file_to_process, io.IOBase):
        self._underlying_stream = file_to_process # its the file itself
    else:
         raise TypeError()

所以我的问题是,在我的 __exit__() 函数中关闭 _underlying_stream 是否是最佳实践/可接受/明智的做法?当它是一条路径时,这是完全有道理的,但如果它是一个传入的流,关闭 self._underlying_stream 充其量是不礼貌的,最坏的情况是危险的 - 我是对的吗考虑到这一点,如果是的话,是否有解决此问题的巧妙方法?

(注意:我考虑过用 io.BufferedReader 包装传入的流,但事实证明关闭也会关闭底层流...)

最佳答案

不会关闭底层流。传入一个已经打开的文件对象意味着调用者已经承担了该对象的责任,并且在 __exit__ 上关闭该对象充其量会非常烦人。

PIL 做了类似的事情,尽管不是在上下文管理器中。传入文件名时,它会在完成读取图像数据后关闭文件对象。它为此设置了一个 bool 标志。相反,传入一个文件对象,它会读取但不会关闭。

我会在这里做同样的事情:

class Foo(object):
    _close_on_exit = False

    def __init__(self, file_to_process):
        if isinstance(file_to_process, str):
            self._underlying_stream = open(file_to_process, "rb") # it's the path to a file
            self._close_on_exit = True
        elif isinstance(file_to_process, io.IOBase):
            self._underlying_stream = file_to_process # its the file itself
        else:
             raise TypeError()

    def __exit__(self, exc_type, exc_value, traceback):
        if self._close_on_exit:
            self._underlying_stream.close()

关于python - 我应该关闭在上下文管理器 __exit__() 函数中传递到我的对象的流(类文件对象)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17489731/

相关文章:

python - atom : hydrogen installed, 但代码未运行(在 macOS 上)

java - 如何添加 .jar 文件以便在我的 IDE (BluJ) 中使用它

c++ - 警告 : control reaches end of non-void function [-Wreturn-type]

c# - StreamReader ReadLine 抛出异常而不是返回 null

python - Django-Taggit : How to print the most used tags?

BLE 的 python3 root 权限

python - 屏蔽格陵兰岛以外的岛屿和轮廓颜色(Python)

java - 获取桌面绝对路径

python - 在通过 for 循环创建内容时检查 csv 文件

java - 如何将声音从 Android 设备流式传输到 Java 服务器?