用Python读取整个文件
如果你读了一个完整的文件,其content = open('Path/to/file', 'r').read()
是文件句柄保持打开状态,直到脚本退出。 有一个更简洁的方法来读取整个文件?
这个问题的答案在某种程度上取决于特定的python实现。
要理解这是什么,请特别注意实际的file
对象。 在你的代码中,这个对象只在expression式中被提及过一次,并且在read()
调用返回后立即变为不可访问。
这意味着文件对象是垃圾。 剩下的唯一问题是“垃圾收集器什么时候收集文件对象?”。
在使用引用计数器的CPython中,这种垃圾会立即被注意到,所以会立即被收集。 其他python实现通常不是这样。
一个更好的解决scheme,确保文件closures,是这种模式:
with open('Path/to/file', 'r') as content_file: content = content_file.read()
它会在块结束后立即closures文件; 即使发生exception。
编辑:把一个更好的点:
除了with
上下文pipe理器设置“自动”调用的file.__exit__()
以外, file.close()
自动调用的唯一方法就是通过file.__del__()
自动调用它(除了明确调用它之外) file.__del__()
。 这导致我们到什么时候__del__()
被调用的问题?
正确编写的程序不能假定在程序终止之前,终结器将在任何时刻运行。
– http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047586.aspx
尤其是:
对象永远不会被明确的销毁 然而,当他们无法到达时,他们可能被垃圾收集。 一个实现允许推迟垃圾回收或者完全忽略垃圾回收 – 只要没有收集到任何仍然可以访问的对象,垃圾收集的执行质量就是一个问题。
[…]
CPython目前使用一个引用计数scheme(可选的)延迟检测循环链接的垃圾,它一收集到大部分对象,但不能保证收集到包含循环引用的垃圾。
– https://docs.python.org/3.5/reference/datamodel.html#objects-values-and-types
(强调我的)
但正如其所暗示的,其他的实现可能有其他的行为。 举个例子,PyPy 有6个不同的垃圾收集实现 !
你可以使用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
实现 :
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()