如何在Python中打开文件列表

时间:2015-04-09 22:40:27

标签: python file

我正在读取数据文件(文本),并生成许多报告,每个报告都写入不同的输出文件(也是文本)。我打开了很长的路:

fP = open('file1','w')

invP = open('inventory','w')

orderP = open('orders','w')

......依此类推,最后有一组相应的close()行。

如果我可以使用for循环打开它们,使用fP名称和文件名列表,我可以保证关闭相同的文件。

我尝试使用fp:filename的词典,但[显然]不起作用,因为fP变量未定义,或者字符串' fP'不是一个好的文件对象名。

由于这些是输出文件,我可能不需要检查公开错误 - 如果我无法打开一个或多个,我无论如何都无法继续。

有没有办法在循环中从名单列表中打开一组文件(不超过10个)?

6 个答案:

答案 0 :(得分:7)

是的,你可以使用列表理解:

filenames = ['file1.txt', 'file2.txt', 'file3.txt'...]
filedata = {filename: open(filename, 'w') for filename in filenames}

现在,所有打开的实例都保存在filedata中,并分配给文件名。

关闭它们:

for file in filedata.values():
    file.close()

答案 1 :(得分:7)

好消息! Python 3.3带来了一种标准的安全方式:

contextlib.ExitStack

来自文档:

  

每个实例都维护一堆已注册的回调函数,这些回调函数在实例关闭时以相反的顺序调用   (...)
  由于注册的回调是按照与注册相反的顺序调用的,因此最终表现为好像已经使用了多个嵌套的with语句和注册的回调集。

以下是如何使用它的示例:

from contextlib import ExitStack

with ExitStack() as stack:
    files = [
        stack.enter_context(open(filename))
        for filename in filenames
    ]
    # ... use files ...

当代码离开with语句时,所有已打开的文件都将被关闭。

这样你也知道如果打开2个文件然后第三个文件无法打开,那么两个已经打开的文件将被正确关闭。此外,如果在with块内随时引发异常,您将看到正确的清理。

答案 2 :(得分:4)

因为您说有很多数据文件。而不是手动将文件名输入列表。您可以将文件名放入列表中。

from os import listdir
from os.path import isfile, join
files_in_dir = [ f for f in listdir('/home/cam/Desktop') if isfile(join('/home/cam/Desktop',f)) ]

现在你可以

for file in files_in_dir:
    with open(file, 'w') as f:
        f.do_something

答案 3 :(得分:3)

使用with keyword保证已打开的文件(以及其他类似资源,称为"上下文管理器")已关闭:

with open(file_path, 'w') as output_file:
    output_file.write('whatever')

退出with块后,文件将被正确关闭 - 即使发生异常。

您可以轻松地遍历所需文件的路径列表:

files = ['fp1.txt', 'inventory', 'orders']
for file in files:
    with open(file, 'w') as current_file:
        current_file.do_some_stuff()

答案 4 :(得分:2)

您可以根据需要打开任意数量的文件,并将它们保存在列表中以便以后关闭它们:

fds = [open(path, 'w') for path in paths]

# ... do stuff with files

# close files
for fd in fds:
    fd.close()

或者你可以使用字典来提高可读性:

# map each file name to a file descriptor
files = {path: open(path, 'w') for path in paths}

# use file descriptors through the mapping
files['inventory'].write("Something")

# close files
for path in files:
    files[path].close()

答案 5 :(得分:1)

如果您事先知道或定义要创建的文件列表,则上述两个答案都很好。但是,如果你想要一个更通用的解决方案,你可以及时构建该列表,使用你的操作系统在磁盘上创建空文件(根据你的操作系统,这是以不同的方式完成),然后以交互方式创建文件列表这样:

import os
working_folder = input("Enter full path for the working folder/directory: ")
os.chdir(working_folder)
filenames_list = os.listdir()

#you can filter too, if you need so:
#filenames_list = [filename for filename in os.listdir() if '.txt' in filename]

#then you can do as Reut Sharabani and A.J. suggest above and make a list of file descriptors
file_descriptors = [open(filename, 'w') for filename in filenames_list]
#or a dictionary as Reut Sharabani suggests (I liked that one Reut :)

#do whatever you need to do with all those files already opened for writing

#then close the files
for fd in file_descriptors:
   fd.close()

可以使用“with”;正如一些人建议的那样,如果你当时只使用一个文件(从开始到结束),但如果你想同时使用所有文件,那么最好是文件描述符的列表或字典。