Python 3.x 输出的最后一行未写入文件
我正在写一个程序来计算DNA文件中不同长度核苷酸模式出现的频率。我正在使用Python 3.3.3。我的问题与文本文件的输出不完整以及使用print命令与输出不匹配有关 这是我对这个问题的第二次编辑,我希望这能把问题弄清楚。在下面的代码中,如果删除open()行,IDE的输出是四行,每行上有一个字母。如果保留该行,则外部输出文件有三行,每行一个字母,第四个字符不打印。使用output命令会导致相同的不完整输出文件Python 3.x 输出的最后一行未写入文件,python-3.x,file-io,Python 3.x,File Io,我正在写一个程序来计算DNA文件中不同长度核苷酸模式出现的频率。我正在使用Python 3.3.3。我的问题与文本文件的输出不完整以及使用print命令与输出不匹配有关 这是我对这个问题的第二次编辑,我希望这能把问题弄清楚。在下面的代码中,如果删除open()行,IDE的输出是四行,每行上有一个字母。如果保留该行,则外部输出文件有三行,每行一个字母,第四个字符不打印。使用output命令会导致相同的不完整输出文件 import sys H = "agtc" pattern = "" for x
import sys
H = "agtc"
pattern = ""
for x in H:
count = 1
if x == 'a' or x == 'g' or x == 't' or x == 'c':
while count < 5:
pattern = x
count += 1
sys.stdout = open ('C:/Users/Owner/Desktop/tetramers.txt', 'a')
print (pattern)
导入系统
H=“agtc”
pattern=“”
对于H中的x:
计数=1
如果x=='a'或x=='g'或x=='t'或x=='c':
当计数小于5时:
图案=x
计数+=1
sys.stdout=open('C:/Users/Owner/Desktop/tetramers.txt','a')
打印(图案)
单个单词的答案是“缓冲””,解决方案是使用关键字(和/或缓冲=1
)的,但让我来告诉您一个过程,帮助您解决这类问题
我在我的计算机上用命令行Python解释器运行了您的示例,它没有出现问题(输出文件包含所有四行)。当您编辑您的问题并提到“IDE的输出”时,我意识到这可能是一种环境差异。我在Python附带的“空闲”IDE中尝试了相同的代码,我看到了您描述的问题(输出文件仅包含三行)
问题是文件输出,所以我只关注查找文件输出代码:
import sys
H = "agtc"
...
for x in H:
...
if ...:
...
...
sys.stdout = open ('C:/Users/Owner/Desktop/tetramers.txt', 'a')
print (...)
我们可以简化为:
import sys
for x in "agtc":
sys.stdout = open('C:/Users/Owner/Desktop/tetramers.txt', 'a')
print(...)
现在是这样了,更容易看到代码打开一个文件四次,但从未显式关闭它
现在,当我第一次看到sys.stdout=…
时,我对此表示怀疑。重新分配stdout不是我每天都做的事情,我想知道这是否是问题的一部分。我尝试了打开
在不更改标准输出的情况下读取文件:
for x in "agtc":
f = open('output.txt', 'a')
print(x, file=f)
它提供相同的输出(三行而不是四行),所以我想重新分配stdout不会有问题。不过,这还是少了一个需要担心的复杂性,所以我们将在解决问题的同时保留更简单的代码
那么接下来呢?我想我知道,但我暂时不告诉自己——这个答案是为了演示思考过程,并为您提供一些调试技术,您可以在将来使用这些技术来确定与文件和缓冲区无关的问题
您在评论中提到,将open()
移动到循环外部会导致一个空文件。这暗示出了一些问题:每次打开文件的速度应该较慢,但不会有不同的输出
让我们确认一下:
f = open('output.txt', 'a')
for x in "agtc":
print(x, file=f)
就像你说的。。。没有输出。(同样,当从空闲运行时,这不是输出。它从我的命令行Python生成所有四行。)
因此,当open()
发生在四个print()
调用之前时,没有输出,但当open()
发生在四个print()
调用之间时,有。。。一些输出,但不是全部。听起来像是一个“篱笆柱”错误。让我们为
循环“展开”:
f = open('output.txt', 'a')
print("a", file=f)
f = open('output.txt', 'a')
print("g", file=f)
f = open('output.txt', 'a')
print("c", file=f)
f = open('output.txt', 'a')
print("t", file=f)
一个循环在展开时的行为应该是相同的,实际上这个循环会产生与以前相同的三行--print()
调用之间的open()
调用。如果我们确保所有的print()
调用都在open()
调用之间,会发生什么情况
f = open('output.txt', 'a')
print("a", file=f)
f = open('output.txt', 'a')
print("g", file=f)
f = open('output.txt', 'a')
print("c", file=f)
f = open('output.txt', 'a')
print("t", file=f)
f = open('output.txt', 'a')
所有四行都在输出中。现在,很明显,在每次print()
之前和之后调用open()。让我们回到我们首先打开文件,然后循环写入的示例。它以前是空白的,但是如果我们应用我们的新知识,print()
在两个open()
s之间似乎是有效的呢
所有行都被输出。因此,并不是每个print()
都需要两个open()
调用。好。但不是很好,因为在完成所有工作后调用open()
显然没有多大意义。完成后关闭文件更有意义。等一下
文件对象是否有close()
方法或类似方法?让我们检查一下文档。官方Python 3教程的“”部分说:
处理完文件后,调用f.close()将其关闭,并释放打开的文件占用的所有系统资源。调用f.close()后,尝试使用文件对象将自动失败
因此有一个close()
方法。让我们在代码中尝试一下:
f = open('output.txt', 'a')
print("a", file=f)
print("g", file=f)
print("c", file=f)
print("t", file=f)
f.close()
嘿,看那个。这是可行的,也是有意义的。好多了
本教程的下一段也很有趣:
处理文件对象时,最好使用with
关键字。这样做的好处是,即使在执行过程中引发异常,文件也会在其套件完成后正确关闭
如果您刚刚开始,这个新关键字现在可能有点混乱——没关系,您可以自己手动清理,直到准备好为止。看起来有点像这样:
with open('output.txt', 'a') as f:
print("a", file=f)
print("g", file=f)
print("c", file=f)
print("t", file=f)
还有一个未解之谜:为什么我的命令行Python也没有出现问题?在空闲状态下运行的Python对保持文件打开是否更敏感?这是值得调查的,但这个答案已经足够长了(而且可能比你想要的要多)。嗨,sph。这是一个堆栈溢出问题的大量代码!如果您进一步缩减代码,将代码缩减到重新编译的最小值,您可能会得到更好的答案(甚至可能自己找到问题)
with open('output.txt', 'a') as f:
print("a", file=f)
print("g", file=f)
print("c", file=f)
print("t", file=f)