python3中自动关闭文件?

nz_*_*_21 -1 python yield file with-statement python-3.x

我的想法是否正确,这会自动关闭文件?

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

f = get_file()
do_stuff(f)
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ers 5

这种方法可以发挥作用,但不是一个好方法。get_file()returns 是一个生成器函数,调用它会返回一个专门的生成器迭代器对象,而不是打开的文件对象本身,不是直接返回。

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

f = get_file()
do_stuff(next(f))
Run Code Online (Sandbox Code Playgroud)

这里next()将生成器推进到该yield点并返回生成的任何内容。此时,上下文with open(...) as f:仍然处于活动状态并且文件不会被关闭。

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

next(f, None)  # give `next()` a default to return when the generator exists
Run Code Online (Sandbox Code Playgroud)

这并不是很理想。您想将函数包装在@contextlib.contextmanager()装饰器中,这要求装饰函数是生成器。然后您必须将其用作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)
Run Code Online (Sandbox Code Playgroud)

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