Python print(): Output Formatting, sep, end, and File Parameters Explained
print() is the first function almost every Python developer learns. Most people use it for a year or more before discovering that it has parameters beyond the obvious — and that those parameters are genuinely useful.
The full signature:
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)The Basics
print() accepts any number of arguments, converts them to strings, and outputs them separated by spaces with a newline at the end:
print("Hello, world!") # Hello, world!print(42) # 42print(3.14) # 3.14print("name:", "Alice", "age:", 30) # name: Alice age: 30You can pass any type — Python calls str() on it automatically. Passing multiple arguments prints them on one line with a space between each.
The sep Parameter
sep controls the separator between multiple arguments. The default is a space:
print("2025", "06", "14", sep="-") # 2025-06-14print("C:", "Users", "Alice", sep="\\") # C:\Users\Aliceprint("a", "b", "c", sep=", ") # a, b, cprint("a", "b", "c", sep="") # abc — no separatorThis is handy when you’re building output that has a specific delimiter, like dates or paths.
The end Parameter
By default, print() adds a newline at the end of its output. Change this with end:
print("Loading", end="")print(".", end="")print(".", end="")print(". Done")# Output: Loading... DoneA common use case is printing loop output on one line:
for i in range(1, 6): print(i, end=" ")# Output: 1 2 3 4 5print() # move to next line when doneThe file Parameter
print() writes to standard output by default, but you can redirect it to any file-like object:
import sys
# Print to standard errorprint("Something went wrong", file=sys.stderr)
# Print to a filewith open("output.log", "w") as log_file: print("Application started", file=log_file) print("Processing complete", file=log_file)This is useful for separating normal output from error messages, or for writing logs without importing the logging module.
The flush Parameter
Python buffers output for efficiency — it collects output and writes it in chunks rather than immediately. Usually this is invisible, but it matters in two situations: progress indicators and long-running loops.
import time
for step in range(5): print(f"Step {step + 1}...", end=" ", flush=True) time.sleep(1)print("Done!")Without flush=True, you might see nothing printed until the loop completes. With it, each step appears immediately as it happens.
String Formatting for Output
Modern Python has several ways to format output. Here’s how they compare:
f-strings (recommended for Python 3.6+)
name = "Alice"score = 94.7
print(f"Player: {name}")print(f"Score: {score:.1f}") # one decimal placeprint(f"Score: {score:>10.1f}") # right-aligned in 10-char fieldprint(f"Score: {score:.0f}%") # no decimal, percent symbolf-strings support the full format spec mini-language inside the braces. Some useful patterns:
price = 1234567.89print(f"Price: ${price:,.2f}") # Price: $1,234,567.89
n = 255print(f"Hex: {n:#x}") # Hex: 0xffprint(f"Binary: {n:b}") # Binary: 11111111
label = "total"print(f"{label:>10}: {price:.2f}") # right-aligns 'total'str.format() for Python 2 compatibility or dynamic format strings
template = "Hello, {}! You have {} messages."print(template.format("Bob", 3))
# Named placeholdersprint("{name} scored {score:.1f}".format(name="Alice", score=94.7))Debugging with print()
Experienced Python developers use print() for quick debugging even when more sophisticated tools are available. Some patterns worth knowing:
# Show variable name and value togetherx = 42print(f"{x = }") # Python 3.8+ — prints: x = 42
# Inspect an object's type alongside its valuedata = [1, 2, 3]print(f"data: {data!r} (type: {type(data).__name__})")
# Track execution flowdef process(items): print(f"process() called with {len(items)} items") result = [item * 2 for item in items] print(f"process() returning: {result[:3]}...") return resultThe !r conversion in f-strings calls repr() instead of str(), which shows strings with their quotes and escape characters — useful when you want to see exactly what’s in a string, including hidden whitespace.
Practical Tips
Use sep and end instead of concatenation. print(a, b, sep=", ") is cleaner than print(str(a) + ", " + str(b)).
Write errors to stderr. print("Error:", msg, file=sys.stderr) keeps error output separate from regular output, which matters when piping program output to another process.
Use flush=True for progress output. Anything involving a progress bar, countdown, or streaming output needs flush=True to appear in real time.
The f"{var = }" syntax is underused. It’s the fastest way to inspect variable values during debugging without typing the variable name twice.