Python buffers file writes by default. It does this for performance purposes. Every time Python writes to a file (or OS-controlled IO stream, like STDOUT), it has to pause execution and hand control over to the OS. If the OS is busy doing something else, or if the disk where you want to write your data is busy doing something else, you could be waiting for a long time for a response. Instead of waiting every time you want to write something, Python writes the data to a buffer in memory, then promises to eventually write the contents of the buffer to a file once the buffer fills up (a process called "flushing" the buffer). This allows execution of your program to continue immediately.
The risk when using write buffers is that if your program crashes before the buffer is flushed to disk, you lose that data. Additionally, if one program writes to a buffer and continues execution in this fashion, there is no guarantee that a concurrently running program will see that data on the disk until the first program somehow flushes the buffer. This second scenario is what is going on in your example: IDLE is running one Python process that writes to a buffer, and you are running a second, concurrent process to check on the file while IDLE is still running. Because the buffer hasn't been flushed in IDLE, you will see nothing written. This does not happen when you run the program from the terminal because the Python process there terminates, and one of the clean-up tasks performed when a process terminates is to flush all the write buffers.
There are many ways to force a buffer flush. Python flushes write buffers automatically when files are closed, so you could try:
f = open("test.txt", "w")
f.write("abc")
f.close()
The preferred way to open files in Python is using a with
statement context manager. When execution exits the with
block, the variables created in the with
statement are told to clean themselves up, which in the case of files means closing them. So you could try:
with open("test.txt", "w") as f:
f.write("abc") # after this block, f is flushed and closed
If you want to keep the file open and manually flush the write buffer, Python gives you the flush
method, so you could also write:
f = open("test.txt", "w")
f.write("abc")
f.flush() # f remains open
Finally, you can tell Python to use a buffer of a different size than the OS default by passing the buffering
argument to open
. A value of 0
tells Python to immediate flush every write to disk. So you could do this:
f = open("test.txt", "w", buffering=0)
f.write("abc") # f remains open