如果您使用content = open('Path/to/file', 'r').read()
读取整个文件,文件句柄将保持打开状态,直到脚本退出?是否有更简洁的方法来读取整个文件?
答案 0 :(得分:496)
该问题的答案在某种程度上取决于特定的python实现。
要了解这是什么,请特别注意实际的file
对象。在您的代码中,该对象在表达式中仅被提及一次,并且在read()
调用返回后立即变得不可访问。
这意味着文件对象是垃圾。唯一剩下的问题是“垃圾收集器什么时候收集文件对象?”。
在CPython中使用引用计数器的,立即注意到这种垃圾,因此会立即收集。对于其他python实现,这通常不正确。
确保文件关闭的更好解决方案是这种模式:
with open('Path/to/file', 'r') as content_file:
content = content_file.read()
总是在块结束后立即关闭文件;即使发生异常。
编辑:更精细一点:
在file.__exit__()
上下文管理器设置中“自动”调用的with
以外,file.close()
被自动调用的唯一方式(即,除了明确调用它之外)你自己,是通过file.__del__()
。这引出了我们__del__()
何时被调用的问题?
正确编写的程序不能假定终结器将在程序终止之前的任何时刻运行。
- https://devblogs.microsoft.com/oldnewthing/20100809-00/?p=13203
特别是:
永远不会明确销毁对象;然而,当它们变得无法到达时,它们可能被垃圾收集。 允许实现推迟垃圾收集或完全省略 - 实现垃圾收集的实现质量问题,只要没有收集到仍然可以访问的对象。
[...]
CPython目前使用带有(可选)延迟检测循环链接垃圾的引用计数方案,它会在大多数对象无法访问时立即收集,但不保证收集包含循环引用的垃圾。
- https://docs.python.org/3.5/reference/datamodel.html#objects-values-and-types
(强调我的)
但正如它所暗示的那样,其他实现可能还有其他行为。例如,PyPy has 6 different garbage collection implementations!
答案 1 :(得分:62)
您可以使用pathlib。
对于Python 3.5及更高版本:
from pathlib import Path
contents = Path(file_path).read_text()
对于较低版本的Python,请使用pathlib2:
$ pip install pathlib2
然后:
from pathlib2 import Path
contents = Path(file_path).read_text()
这是实际的read_text
implementation:
def read_text(self, encoding=None, errors=None):
"""
Open the file in text mode, read it, and close the file.
"""
with self.open(mode='r', encoding=encoding, errors=errors) as f:
return f.read()
答案 2 :(得分:1)
与其将文件内容作为单个字符串检索, 将内容存储为文件包含的所有行的列表会很方便:
with open('Path/to/file', 'r') as content_file:
content_list = content_file.read().strip().split("\n")
可以看出,需要将串联方法.strip().split("\n")
添加到the main answer in this thread。
在这里,.strip()
只是删除了整个文件字符串结尾处的空格和换行符,
.split("\n")
通过在每个换行符 \ n 处拆分整个文件字符串来生成实际列表。
此外, 这样,整个文件内容可以存储在变量中,这在某些情况下可能是需要的,而不是像this previous answer所指出的那样逐行循环遍历文件。
答案 3 :(得分:0)
好吧,如果必须逐行读取文件才能使用每一行,则可以使用
with open('Path/to/file', 'r') as f:
s = f.readline()
while s:
# do whatever you want to
s = f.readline()
甚至更好的方法:
with open('Path/to/file') as f:
for line in f:
# do whatever you want to