如果我要阅读Python 3.2中的一些文件,比如30-40,我想将文件引用保留在列表中
(所有文件都在公共文件夹中)
无论如何我可以将所有文件打开到列表中各自的文件句柄,而无需通过file.open()函数单独打开每个文件
答案 0 :(得分:6)
这很简单,只需根据文件路径列表使用列表推导。或者,如果您只需要一次访问它们,请使用生成器表达式以避免一次打开所有四十个文件。
list_of_filenames = ['/foo/bar', '/baz', '/tmp/foo']
open_files = [open(f) for f in list_of_filenames]
如果您想要处理某个目录中的所有文件,请使用os.listdir
功能:
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_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或更高版本,我建议您使用ExitStack
以获得更多便利。
答案 1 :(得分:1)
os
库(特别是listdir
)应该为您提供所需的基本工具:
import os
print("\n".join(os.listdir())) # returns all of the files (& directories) in the current directory
显然你会想要用它们调用open
,但是这会以可迭代的形式提供文件(我认为这是你所面临的问题的关键)。此时,您可以执行for
循环并打开它们(或其中一些)。
快速警告:Jon Clements在Henry Keiter的回答评论中指出,你应该注意目录,这些目录会在os.listdir
和文件中显示出来。
此外,现在是编写一些过滤语句的好时机,以确保您只尝试打开正确类型的文件。你可能认为你只会在现在目录中拥有.txt文件,但是有一天你的操作系统(或用户)会有一个聪明的想法,在那里放一些东西,这可能会抛出代码中的扳手。
幸运的是,快速过滤器可以做到这一点,你可以通过几种方式实现(我只是展示一个正则表达式过滤器):
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))
请注意,我没有检查是否有权访问该文件,所以如果我能够在目录中看到该文件但没有读取它的权限,那么我会遇到异常。