Python—打开连续文件而不实际打开每个文件
如果我要在Python3.2中读取许多文件,比如30-40,我想将文件引用保存在一个列表中 (所有文件都在一个公用文件夹中)Python—打开连续文件而不实际打开每个文件,python,python-3.x,Python,Python 3.x,如果我要在Python3.2中读取许多文件,比如30-40,我想将文件引用保存在一个列表中 (所有文件都在一个公用文件夹中) 是否还有其他方法可以将所有文件打开到列表中各自的文件句柄,而不必通过file.open()函数单独打开每个文件?这很简单,只要根据文件路径列表使用列表理解即可。或者,如果一次只需要访问一个文件,请使用生成器表达式以避免同时打开所有40个文件 list_of_filenames = ['/foo/bar', '/baz', '/tmp/foo'] open_files =
是否还有其他方法可以将所有文件打开到列表中各自的文件句柄,而不必通过file.open()函数单独打开每个文件?这很简单,只要根据文件路径列表使用列表理解即可。或者,如果一次只需要访问一个文件,请使用生成器表达式以避免同时打开所有40个文件
list_of_filenames = ['/foo/bar', '/baz', '/tmp/foo']
open_files = [open(f) for f in list_of_filenames]
如果要处理某个目录中的所有文件,请使用以下函数:
import os
open_files = [open(f) for f in os.listdir(some_path)]
我假设这里有一个简单的平面目录,但是请注意,os.listdir
返回给定目录中所有文件对象的路径列表,无论它们是“真实”文件还是目录。因此,如果要打开的目录中有目录,则需要使用os.path.isfile
筛选结果:
import os
open_files = [open(f) for f in os.listdir(some_path) if os.path.isfile(f)]
另外,os.listdir
只返回裸文件名,而不是整个路径,因此如果当前工作目录不是some\u path
,则需要使用os.path.join
创建绝对路径
import os
open_files = [open(os.path.join(some_path, f)) for f in os.listdir(some_path)
if os.path.isfile(f)]
使用生成器表达式:
import os
all_files = (open(f) for f in os.listdir(some_path)) # note () instead of []
for f in all_files:
pass # do something with the open file here.
在所有情况下,确保在处理完文件后关闭这些文件。如果您可以升级到Python 3.3或更高版本,我建议您使用一个更方便的版本。操作系统
库(尤其是listdir
)应该为您提供所需的基本工具:
import os
print("\n".join(os.listdir())) # returns all of the files (& directories) in the current directory
显然,您希望使用它们调用open
,但这会以一种可移植的形式提供文件(我认为这是您面临的问题的关键)。此时,您可以对
执行一个循环,然后将它们全部(或部分)打开
快速警告:Jon Clements在Henry Keiter回答的评论中指出,您应该注意目录,它将与文件一起出现在os.listdir
中
此外,现在是编写一些筛选语句的好时机,以确保只打开正确类型的文件。您可能会认为,现在目录中只有.txt文件,但总有一天,您的操作系统(或用户)会想出一个聪明的主意,在其中放入其他文件,这可能会对您的代码造成影响
幸运的是,一个快速过滤器可以做到这一点,您可以通过两种方式做到这一点(我将展示一个正则表达式过滤器):
请注意,我没有检查是否有权限访问该文件,因此如果我能够在目录中查看该文件,但没有读取该文件的权限,那么我将遇到异常。…什么?您想在不打开文件的情况下打开文件?您的意思是不在系统上进行调用,还是不在代码中键入file.open()
30-40次?前者是不可能的(文件需要被访问到…呃,被访问)。我指的是后者,即不必执行第二步,在我的代码中多次键入file.open(),然后使用循环。如果这对您来说是新的,我强烈建议您遵循一个教程。第二个教程正是我想要的,即不必单独键入每个文件名。谢谢,并且os.listdir
将返回无法正确打开的目录,因此,您可能希望在您的示例中使用os.path.isfile
或等效文件…@JonClements为了简单起见,我假设目标目录中没有目录,但是是的,我会记下这一点。遗憾的是,OP使用的是Python 3.2,而不是Python 3.3,或者他可以使用ExitStack
@DSM是的。如果有人感兴趣,可以链接到ExitStack
文档。它是在3.3中引入的,基本上您只需在每个open
调用周围包装一个上下文管理器,就可以为每个文件对象获得上下文管理器的功能,即使它们是在列表中创建的。
import os,re
scripts=re.compile(".*\.py$")
files=[open(x,'r') for x in os.listdir() if os.path.isfile(x) and scripts.match(x)]
files=map(lambda x:x.read(),files)
print("\n".join(files))