如何使用with关闭此函数中的文件?

时间:2012-12-20 14:32:10

标签: python optimization file-io

我有以下功能。程序查看每个文件并将所有4个文件中出现的行打印到新文件中。我试过file1.close()但是我收到关于关闭一个集合的错误?我想我可以使用with语句,但不知道如何做到这一点,我对编程很新。

def secretome():
    file1 = set(line.strip() for line in open(path + "goodlistSigP.txt"))
    file2 = set(line.strip() for line in open(path + "tmhmmGoodlist.txt"))
    file3 = set(line.strip() for line in open(path + "targetpGoodlist.txt"))
    file4 = set(line.strip() for line in open(path + "wolfPsortGoodlist.txt"))
    newfile = open(path + "secretome_pass.txt", "w")
    for line in file1 & file2 & file3 & file4:
        if line:
            newfile.write(line + '\n')
    newfile.close()

4 个答案:

答案 0 :(得分:4)

我建议通过将您的集合生成提取到函数中来删除重复:

def set_from_file(path):
    with open(path) as file:
        return set(lines.strip() for line in file)

def secretome():
    files = ["goodlistSigP.txt", "tmhmmGoodlist.txt", "targetpGoodlist.txt", "wolfPsortGoodlist.txt"]
    data = [set_from_file(os.path.join(path, file)) for file in files]
    with open(path + "secretome_pass.text", "w") as newfile:
        newfile.writelines(line + "/n" for line in set.union(*data) if line)

请注意,您在代码中正在进行交集,但是您谈到了想要一个联合,所以我在这里使用了union()。还有一些list comprehensions/generator expressions

答案 1 :(得分:1)

这是一个完全不同于我原来的方向(Lattyware打败了我):

您可以定义一个函数:

def file_lines(fname):
    with open(fname) as f:
         for line in f:
             yield line

现在,您可以使用itertools.chain来迭代文件:

import itertools
def set_from_file(path):
    filenames = ("name1","name2","name3",...)  #your input files go here
    lines = itertools.chain.from_iterable(itertools.imap(file_lines,filenames))
    #lines is an iterable object.  
    #At this point, virtually none of your system's resources have been consumed
    with open("output",'w') as fout:
         #Now we only need enough memory to store the non-duplicate lines :)
         fout.writelines(set( line.strip()+'\n' for line in lines) )

答案 2 :(得分:1)

这似乎是一种非常复杂的方式。我建议像我在这里给出的例子。

import fileinput
files = ['file1.txt','file2.txt','file3.txt','file4.txt']  
output = open('output.txt','w')

for file in files:
    for line in fileinput.input([file]):
        output.write(line)
    output.write('\n')

output.close()

此代码创建一个包含文件的列表(用必需的文件路径替换名称),创建一个文件来存储每个文件的输出,然后使用fileinput模块简单地遍历它们,逐行遍历每个文件,将每行打印到输出文件中。 'output.write('\ n')'确保打印下一个文件的行从输出文件中的新行开始。

答案 3 :(得分:0)

你可以将它放入发电机:

def closingfilelines(*a):
    with open(*a) as f:
        for line in f:
            yield f

并在当前使用open()的地方使用它。

当生成器运行时,文件保持打开状态,如果生成器耗尽,它将被关闭。

如果生成器对象为.close() d或删除,则会发生同样的情况 - 在这种情况下,生成器会获得GeneratorExit异常,这也会使with子句保留。< / p>