Python buffers file writes by default. 这样做是出于性能目的。每次 Python 写入文件(或操作系统控制的 IO 流,如 STDOUT)时,它都必须暂停执行并将控制权交给操作系统。如果操作系统正忙于做其他事情,或者如果您要写入数据的磁盘正忙于做其他事情,您可能会等待很长时间才能得到响应。不是每次你想写东西时都等待,Python 将数据写入内存中的缓冲区,然后承诺在缓冲区填满后最终将缓冲区的内容写入文件(称为“刷新”缓冲区的过程)。这允许您的程序立即继续执行。
使用写缓冲区的风险在于,如果您的程序在缓冲区刷新到磁盘之前崩溃,您会丢失该数据。此外,如果一个程序写入缓冲区并以这种方式继续执行,则无法保证并发运行的程序会在磁盘上看到该数据,直到第一个程序以某种方式刷新缓冲区。第二种情况是您的示例中发生的情况:IDLE 正在运行一个写入缓冲区的 Python 进程,并且您正在运行第二个并发进程以在 IDLE 仍在运行时检查文件。因为缓冲区在 IDLE 中没有被刷新,所以您将看不到任何写入。当您从终端运行程序时不会发生这种情况,因为那里的 Python 进程终止,而当进程终止时执行的清理任务之一是刷新所有写入缓冲区。
有很多方法可以强制刷新缓冲区。 Python flushes write buffers automatically when files are closed,你可以试试:
f = open("test.txt", "w")
f.write("abc")
f.close()
在 Python 中打开文件的首选方法是使用 with statement context manager。当执行退出with 块时,with 语句中创建的变量被告知要清理它们自己,这对于文件来说意味着关闭它们。所以你可以试试:
with open("test.txt", "w") as f:
f.write("abc") # after this block, f is flushed and closed
如果您想保持文件打开并手动刷新写入缓冲区,Python 会为您提供flush method,因此您也可以编写:
f = open("test.txt", "w")
f.write("abc")
f.flush() # f remains open
最后,您可以通过传递buffering argument to open 来告诉 Python 使用与操作系统默认大小不同的缓冲区。 0 的值告诉 Python 在每次写入磁盘时立即刷新。所以你可以这样做:
f = open("test.txt", "w", buffering=0)
f.write("abc") # f remains open