自动关闭 python3 中的文件?

automatically closing a file in python3?

我认为这会自动关闭文件是对的吗?

def get_file():
    with open("file.csv", "rb") as f:
        yield f

f = get_file()
do_stuff(f)

如果不是,我如何编写一个 returns 文件对象的函数,同时确保它在接收器使用完文件后关闭文件?

这很可能行不通。在函数中使用 yield 使函数 return 成为生成器,它将生成第一个 yield 值作为第一个元素,并且 运行 函数直到需要另一个元素时的下一个 yield。

这不是您所期望的。恐怕无法确定调用代码何时完成文件。有可能(我不太了解 Python 的内存管理)是文件的操作系统句柄(文件描述符)在文件被垃圾回收时关闭。但是,这需要您清除所有直接和间接引用,这可能很棘手。

with open() 块中执行完整的文件处理要容易得多,而且可读性要好得多。

这个 sort 可以工作,但不是一个好的方法。 get_file() returns是一个generator function, and calling it returns a specialised generator iterator object,不是打开的文件对象本身,不是直接的。

当您使用生成器上的 next() 来处理文件时,它会起作用:

f = get_file()
do_stuff(next(f))

此处 next() 将生成器推进到 yield 点,并且 returns 产生任何结果。那时 with open(...) as f: 的上下文保持活动状态并且文件不会关闭。

但是,要 关闭 文件,您必须再次调用 next() 并防止引发 StopIteration 异常:

next(f, None)  # give `next()` a default to return when the generator exists

这不是很理想。您想要将您的函数包装在 @contextlib.contextmanager() decorator 中, 要求 装饰函数是一个生成器。然后你可以必须使用get_file()作为上下文管理器:

from contextlib import contextmanager

@contextmanager
def get_file():
    with open("file.csv", "rb") as f:
        yield f

with get_file() as f:
    do_stuff(f)

像这样使用get_file()没有太多,因为你也可以只使用return open("file.csv", "rb")并依赖文件对象本身上下文管理器。但是,如果您要将其他任务添加到 get_file() 需要访问该文件或需要知道您已关闭它的函数,那么您很可能有一个自定义上下文管理器的好用例。