-1

如果我要读取 Python 3.2 中的多个文件,比如 30-40,并且我想将文件引用保存在列表中

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

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

4

2 回答 2

6

这很简单,只需根据您的文件路径列表使用列表推导即可。或者,如果您一次只需要访问一个,请使用生成器表达式来避免同时打开所有 40 个文件。

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更方便的 .

于 2013-09-24T16:18:09.577 回答
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))

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

于 2013-09-24T16:21:23.660 回答