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



我有一个对象,我希望能够在上面使用with关键字。我对实现上下文管理器的实用性感到满意,但我遇到了一个最佳实践类型的问题。

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

所以__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做了类似的事情,尽管不是在上下文管理器中。当传入文件名时,它将在读取完图像数据后关闭fileobject。它设置了一个布尔标志。相反,传入一个文件对象,它将读取但不会关闭。

我在这里也会这么做:

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()

相关内容

  • 没有找到相关文章

最新更新