Python 如何使用with关闭此函数中的文件?
我有以下功能。程序查看每个文件,并将所有4个文件中出现的行打印到一个新文件中。我尝试了Python 如何使用with关闭此函数中的文件?,python,optimization,file-io,Python,Optimization,File Io,我有以下功能。程序查看每个文件,并将所有4个文件中出现的行打印到一个新文件中。我尝试了file1.close(),但在关闭集合时出错了?我想我可以使用和语句,但不知道如何做,我对编程非常陌生 def secretome(): file1 = set(line.strip() for line in open(path + "goodlistSigP.txt")) file2 = set(line.strip() for line in open(path + "tmhmmGood
file1.close()
,但在关闭集合时出错了?我想我可以使用和语句,但不知道如何做,我对编程非常陌生
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()
我建议通过将集合生成提取到函数中来消除重复:
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)
def file_lines(fname):
with open(fname) as f:
for line in f:
yield line
请注意,您正在代码中进行交集,但您谈到想要一个联合,所以我在这里使用了union()
。还有几个问题。我建议通过将集合生成提取到函数中来消除重复:
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)
def file_lines(fname):
with open(fname) as f:
for line in f:
yield line
请注意,您正在代码中进行交集,但您谈到想要一个联合,所以我在这里使用了union()
。还有几个。您可以将其放入发电机中:
def closingfilelines(*a):
with open(*a) as f:
for line in f:
yield f
并在当前使用open()
的位置使用它
生成器运行时,文件保持打开状态,如果生成器已耗尽,则会关闭
如果生成器对象是.close()
d或已删除,则会发生同样的情况-在这种情况下,生成器将获得GeneratorExit
异常,这使得with
子句也被保留。您可以将其放入生成器中:
def closingfilelines(*a):
with open(*a) as f:
for line in f:
yield f
并在当前使用open()
的位置使用它
生成器运行时,文件保持打开状态,如果生成器已耗尽,则会关闭
如果生成器对象是.close()
d或drop,也会发生同样的情况-在这种情况下,生成器会得到一个GeneratorExit
异常,这使得with
子句也被保留。采取与我原来的方向完全不同的方法(Lattyware打败了我):
您可以定义一个函数:
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)
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) )
这与我最初的(哪种厕所比我更先进)完全不同:
您可以定义一个函数:
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)
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) )
这似乎是一种非常复杂的方法。我会提出一些类似于我在这里给出的例子的建议
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')”确保下一个文件行的打印从输出文件中的新行开始。这似乎是一种非常复杂的方法。我会提出一些类似于我在这里给出的例子的建议
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')”确保下一个文件行的打印从输出文件中的新行开始。我不认为open(*a)
是您想要的。。。是吗?@mgilson为什么不是?因此,我可以根据OP的需要设置set(line.strip(),用于closingfilelines(path+“goodlistSigP.txt”)
,如果需要,也可以设置closingfilelines(path+“goodlistSigP.txt”,“r+b”,1024)
。诚然,我的解决方案不如将set()
构建到函数中的解决方案好,但这并不是那么糟糕,是吗?我明白了,我不确定你是想隐式地对文件进行循环,还是想传递一个“模式”(这就是我的“是吗?”问题)。考虑过这个问题后,我对这个解决方案很满意。它解决了OP最初的问题“如何在这些开放语句周围获得上下文管理器”+1来自meI不要认为open(*a)
是您在这里想要的。。。是吗?@mgilson为什么不是?因此,我可以根据OP的需要设置set(line.strip(),用于closingfilelines(path+“goodlistSigP.txt”)
,如果需要,也可以设置closingfilelines(path+“goodlistSigP.txt”,“r+b”,1024)
。诚然,我的解决方案不如将set()
构建到函数中的解决方案好,但这并不是那么糟糕,是吗?我明白了,我不确定你是想隐式地对文件进行循环,还是想传递一个“模式”(这就是我的“是吗?”问题)。考虑过这个问题后,我对这个解决方案很满意。它解决了OP最初的问题“如何在这些开放语句周围获得上下文管理器”+我认为你的新文件没有换行符。否则,答案很好。比我快一分钟左右。作为旁注,可能newfile.writelines(line+'\n'代表line in…if line)
可能有点cleaner@mgilson很好的建议,我会进行更改。这是一个有趣的itertools
。如果您感兴趣,请参阅我的(新的、非重复的)答案:)最后一条注释:set().union(*data)
更简单地写为set.union(*data)
,因为您传入的第一个对象已经是set
的实例。我认为您的新文件没有换行符。否则,答案很好。比我快一分钟左右。作为旁注,可能newfile.writelines(line+'\n'代表line in…if line)
可能有点cleaner@mgilson很好的建议,我会进行更改。这是一个有趣的itertools
。如果您感兴趣,请参阅我的(新的、非重复的)答案:)最后一条评论:set().union(*data)
更简单(在本例中)写为set.union(*data)
,因为您传入的第一个对象已经是set
的一个实例。为什么不在fileinput.input(列表):