我正在读取数据文件(文本),并生成许多报告,每个报告都写入不同的输出文件(也是文本)。我打开了很长的路:
fP = open('file1','w')
invP = open('inventory','w')
orderP = open('orders','w')
......依此类推,最后有一组相应的close()行。
如果我可以使用for循环打开它们,使用fP名称和文件名列表,我可以保证关闭相同的文件。
我尝试使用fp:filename
的词典,但[显然]不起作用,因为fP变量未定义,或者字符串' fP'不是一个好的文件对象名。
由于这些是输出文件,我可能不需要检查公开错误 - 如果我无法打开一个或多个,我无论如何都无法继续。
有没有办法在循环中从名单列表中打开一组文件(不超过10个)?
答案 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)
来自文档:
每个实例都维护一堆已注册的回调函数,这些回调函数在实例关闭时以相反的顺序调用 (...)
由于注册的回调是按照与注册相反的顺序调用的,因此最终表现为好像已经使用了多个嵌套的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”;正如一些人建议的那样,如果你当时只使用一个文件(从开始到结束),但如果你想同时使用所有文件,那么最好是文件描述符的列表或字典。