The file.readline() method reads a single line from an open file stream up to and including the trailing newline character (\n). It provides fine-grained control over file streams, making it possible to stream multi-gigabyte log files and tabular datasets without exhausting system memory.
Parent Guide: For an overview of file opening modes, encoding, and stream management, visit the Python File Handling guide.
The readline() method is called directly on an open file object:
file.readline(size=-1)
| Parameter | Type | Default | Description |
|---|---|---|---|
size |
int |
-1 |
Optional. The maximum number of bytes (in binary mode) or characters (in text mode) to read. If negative or omitted, reads until the next newline (\n) or End-of-File (EOF). |
Return Value: Returns a string (str in text mode) or bytes (bytes in binary mode). When the end of the file is reached, it returns an empty string ("") or empty bytes (b"").
Assume we have a file named sample.txt with the following content:
Python File Handling
Line 2: Fast & Reliable
Line 3: Clean Syntax
Each call to readline() advances the file pointer to the start of the next line:
with open("sample.txt", "r", encoding="utf-8") as f:
line1 = f.readline()
line2 = f.readline()
line3 = f.readline()
print(repr(line1))
print(repr(line2))
print(repr(line3))
'Python File Handling\n'
'Line 2: Fast & Reliable\n'
'Line 3: Clean Syntax'
Notice that each line retains its trailing newline character (\n), except possibly the very last line if the file ends without a final newline.
A common source of bugs in file processing is confusing an empty line (a blank line containing only a newline) with the End of File (EOF):
"\n" (length 1). In Python, bool("\n") evaluates to True."" (empty string, length 0). In Python, bool("") evaluates to False.with open("data_with_blank_lines.txt", "r") as f:
while True:
line = f.readline()
if line == "": # Exact EOF check
print("Reached End of File.")
break
if line == "\n":
print("Encountered a blank line (skipping).")
continue
print("Data:", line.rstrip("\r\n"))
if not line.strip(): break to detect the end of a file! If your file contains an intentional blank line in the middle, that condition will trigger prematurely and abort reading the rest of the file. Always test against line == "" for EOF.
Because print() adds its own newline by default, printing lines read with readline() results in double-spacing unless stripped or configured:
rstrip('\r\n') (Recommended)Using str.rstrip('\r\n') strips only carriage returns and newlines, preserving any leading indentation or trailing spaces that may be part of your data format (such as Python source code or fixed-width columns):
clean_line = raw_line.rstrip("\r\n")
print(..., end="")with open("sample.txt", "r") as f:
while (line := f.readline()):
print(line, end="") # Suppress print's default newline
The optional size argument limits the number of characters read from the current line. If the line is longer than size, only the first size characters are returned, and subsequent calls continue reading the remainder of the same line:
with open("sample.txt", "r") as f:
part1 = f.readline(6) # First 6 characters
part2 = f.readline(5) # Next 5 characters
remainder = f.readline() # Rest of the first line
print("Part 1: ", repr(part1))
print("Part 2: ", repr(part2))
print("Remainder:", repr(remainder))
Part 1: 'Python'
Part 2: ' File'
Remainder: ' Handling\n'
This feature is helpful when processing corrupted or untrusted files that might contain an unexpectedly huge single line that would otherwise exhaust available RAM.
When you need to loop over lines using readline(), there are three common patterns in modern Python:
The walrus operator (:=) assigns and evaluates in one concise statement:
with open("sample.txt", "r") as f:
while (line := f.readline()):
print(line.rstrip("\r\n"))
Python's built-in iter(callable, sentinel) calls a zero-argument function repeatedly until it returns the sentinel value. Since readline() returns "" at EOF, this creates a clean iterator:
with open("sample.txt", "r") as f:
for line in iter(f.readline, ""):
print(line.rstrip("\r\n"))
Python provides multiple ways to read lines. Here is how they compare in performance, memory, and idiomatic use:
| Technique | Memory Usage | Best For | Code Pattern |
|---|---|---|---|
file.readline() |
Minimal (Ο(1) line buffer) | Manual step-by-step reading, skipping specific headers, or interactive streaming. | line = f.readline() |
for line in file: |
Minimal (Ο(1) buffered generator) | Standard & Most Pythonic: iterating over an entire file sequentially. | for line in f: |
file.readlines() |
High (Ο(N) loads entire file into list) | Small files where you need random indexing (e.g. lines[5]) or exact line count upfront. |
lines = f.readlines() |
Always manage files using a with context manager so file descriptors are released automatically even if exceptions occur. Common file I/O exceptions include:
try:
with open("missing_config.conf", "r", encoding="utf-8") as f:
header = f.readline()
except FileNotFoundError:
print("Error: The target file was not found.")
except PermissionError:
print("Error: Read permissions denied for this file.")
except UnicodeDecodeError:
print("Error: File content does not match UTF-8 encoding.")
In production applications, configuration files often contain comment lines starting with #, blank lines, and key-value pairs separated by =. Using readline(), we can stream and parse these files without storing unneeded comment lines in memory:
import io
# Mock file stream using io.StringIO for demonstration
config_data = (
"# Production App Config\n"
"PORT=8080\n"
"HOST=127.0.0.1\n\n"
"# Performance Flags\n"
"MAX_CONNECTIONS=500\n"
"ENABLE_CACHE=true\n"
)
def parse_config_stream(stream):
settings = {}
while (raw_line := stream.readline()):
line = raw_line.strip()
# Skip blank lines and comments
if not line or line.startswith("#"):
continue
if "=" in line:
key, value = line.split("=", 1)
settings[key.strip()] = value.strip()
return settings
# Execute parser
stream = io.StringIO(config_data)
parsed = parse_config_stream(stream)
# Self-checking unit assertions
assert parsed["PORT"] == "8080"
assert parsed["HOST"] == "127.0.0.1"
assert parsed["MAX_CONNECTIONS"] == "500"
assert parsed["ENABLE_CACHE"] == "true"
assert len(parsed) == 4
print("Parsed Configuration:", parsed)
print("All configuration parser assertions passed successfully!")
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.