ZetCode

Python flush Function

Last modified March 26, 2025

This comprehensive guide explores Python's flush function, which forces immediate writing of buffered data to disk. We'll cover its purpose, when to use it, and practical examples demonstrating its importance in file operations and output buffering scenarios.

Basic Definitions

The flush method forces the internal buffer to write data to the disk immediately. File operations are often buffered for performance, meaning data isn't written immediately. flush ensures data is physically written when needed.

Buffering improves performance by reducing disk I/O operations. However, there are cases where immediate writing is required, such as logging critical events or when another process needs to read the data immediately.

The flush method is available on file objects, stdout, and other stream objects. It doesn't close the file but ensures all buffered data is written to the underlying storage.

Basic File Flushing

This example demonstrates the basic usage of flush to ensure data is written to disk immediately. Without flushing, data might remain in buffers.

basic_flush.py
# Writing to a file with explicit flushing
file = open('output.txt', 'w')
file.write('This data might be buffered\n')
file.flush()  # Force write to disk
print("Data has been flushed to disk")
file.close()

In this example, we write data to a file and immediately call flush to ensure it's written to disk. Without this call, the data might remain in memory buffers until the file is closed or the buffer fills up.

This is particularly important for critical data that must persist immediately, such as transaction logs or system status updates. The flush call provides certainty that the data is physically stored.

Flushing Standard Output

The flush method is also available on sys.stdout, which is useful when you need to ensure output appears immediately in consoles or pipes.

stdout_flush.py
import sys
import time

print("This appears immediately", flush=True)
print("This might be buffered")

for i in range(5):
    print(f"Progress: {i+1}/5", end='\r')
    time.sleep(1)
print("\nDone", flush=True)

This example shows two ways to flush stdout: using the flush parameter in print and calling sys.stdout.flush(). The progress counter demonstrates why flushing is needed for real-time updates.

Without flushing, the progress updates might not appear until the loop completes. Flushing ensures each update is visible immediately, creating a smooth progress indicator.

Flushing in Logging Systems

Logging systems often use buffering for performance. This example shows how to ensure log entries are written immediately when critical events occur.

logging_flush.py
import logging

# Configure basic logging
logging.basicConfig(
    filename='app.log',
    level=logging.INFO,
    format='%(asctime)s - %(message)s'
)

def log_critical_event(message):
    logging.info(message)
    logging.getLogger().handlers[0].flush()
    print(f"Logged: {message}", flush=True)

log_critical_event("System started")
log_critical_event("Critical error detected!")

This example demonstrates flushing both a log file and stdout for critical events. The handler's flush method ensures the log entry is written to disk immediately, not just stored in memory buffers.

In production systems, this technique is valuable for debugging crashes or monitoring critical systems where log entries must persist immediately.

Flushing with Context Managers

While context managers automatically close files, you might still need to flush data before the context ends. This example shows how to do both.

context_flush.py
# Using flush within a context manager
with open('data.txt', 'w') as file:
    file.write('Initial data\n')
    file.flush()  # Ensure data is written before continuing
    
    # Simulate some processing
    import time
    time.sleep(2)
    
    file.write('Additional data\n')
    # No explicit flush needed - context manager will handle it

This example shows flushing within a context manager to ensure data is written at specific points, while still benefiting from automatic closing. The first write is flushed immediately, while the second relies on the context manager.

This pattern is useful when writing data in stages where intermediate results should be persisted before continuing with potentially risky operations.

Flushing in Network Operations

Network sockets and pipes also use buffering. This example demonstrates flushing when writing to a network socket to ensure data is sent immediately.

network_flush.py
import socket

def send_immediate_message(host, port, message):
    with socket.create_connection((host, port)) as sock:
        sock.sendall(message.encode('utf-8'))
        sock.send(b'\x04')  # End-of-transmission
        sock.flush()  # Ensure all data is sent
        print("Message sent and flushed", flush=True)

# Example usage (would need a server to actually work)
# send_immediate_message('localhost', 9000, 'Urgent update')

This example shows flushing a network socket to ensure all buffered data is sent immediately. Network protocols often require timely delivery of messages, making flush crucial for proper communication.

Without flushing, small messages might be delayed as the system waits for more data to fill packets efficiently. Flushing overrides this optimization when immediate delivery is more important than network efficiency.

Best Practices

Source References

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Python tutorials.