自动关闭 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()
需要访问该文件或需要知道您已关闭它的函数,那么您很可能有一个自定义上下文管理器的好用例。
我认为这会自动关闭文件是对的吗?
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()
需要访问该文件或需要知道您已关闭它的函数,那么您很可能有一个自定义上下文管理器的好用例。