Python - 打开连续文件而不是实际打开每个文件

时间:2013-09-24 16:11:45

标签: python python-3.x

如果我要阅读Python 3.2中的一些文件,比如30-40,我想将文件引用保留在列表中

(所有文件都在公共文件夹中)

无论如何我可以将所有文件打开到列表中各自的文件句柄,而无需通过file.open()函数单独打开每个文件

2 个答案:

答案 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))

请注意,我没有检查是否有权访问该文件,所以如果我能够在目录中看到该文件但没有读取它的权限,那么我会遇到异常。