Python File Handling
Python provides built-in functions for reading, writing, and manipulating files. Understanding file handling is essential for working with data, configurations, logs, and more.
Opening and Closing Files
python
# Basic file operations
file = open("example.txt", "r") # Open for reading
content = file.read()
file.close() # Always close!
# Better: use context manager (auto-closes)
with open("example.txt", "r") as file:
content = file.read()
# File is automatically closed hereAlways use with statements for file handling. They guarantee the file is closed even if an error occurs.
File Modes
| Mode | Description | Creates File | Overwrites |
|---|---|---|---|
"r" | Read (default) | No | No |
"w" | Write | Yes | Yes |
"a" | Append | Yes | No |
"x" | Create (fails if exists) | Yes | No |
"r+" | Read and write | No | No |
"w+" | Write and read | Yes | Yes |
"b" | Binary mode (add to above) | — | — |
python
# Write mode (creates or overwrites)
with open("output.txt", "w") as f:
f.write("Hello, World!\n")
# Append mode (adds to end)
with open("output.txt", "a") as f:
f.write("Another line\n")
# Read mode
with open("output.txt", "r") as f:
print(f.read())
# Hello, World!
# Another lineReading Files
Read Entire File
python
with open("data.txt", "r") as f:
content = f.read()
print(content)Read Line by Line
python
# readline() - one line at a time
with open("data.txt", "r") as f:
line1 = f.readline() # First line
line2 = f.readline() # Second line
# readlines() - all lines as list
with open("data.txt", "r") as f:
lines = f.readlines()
for line in lines:
print(line.strip())
# Iterate directly (most memory-efficient)
with open("data.txt", "r") as f:
for line in f:
print(line.strip())Read with Encoding
python
# Specify encoding (important for non-ASCII text)
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read()Writing Files
python
# Write a string
with open("output.txt", "w") as f:
f.write("Line 1\n")
f.write("Line 2\n")
# Write multiple lines
lines = ["Python\n", "is\n", "awesome\n"]
with open("output.txt", "w") as f:
f.writelines(lines)
# Write with print
with open("output.txt", "w") as f:
print("Hello, World!", file=f)
print("Python is great!", file=f)
# Formatted writing
students = [("Alice", 90), ("Bob", 85), ("Charlie", 92)]
with open("grades.txt", "w") as f:
f.write("Name Grade\n")
f.write("-" * 20 + "\n")
for name, grade in students:
f.write(f"{name:<12}{grade}\n")Working with CSV Files
python
import csv
# Writing CSV
students = [
["Name", "Age", "Grade"],
["Alice", 25, "A"],
["Bob", 22, "B"],
["Charlie", 28, "A"],
]
with open("students.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(students)
# Reading CSV
with open("students.csv", "r") as f:
reader = csv.reader(f)
header = next(reader) # Skip header
for row in reader:
print(f"{row[0]}: Age {row[1]}, Grade {row[2]}")
# Using DictReader/DictWriter
with open("students.csv", "r") as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['Name']} got {row['Grade']}")Working with JSON Files
python
import json
# Write JSON
data = {
"name": "Alice",
"age": 30,
"skills": ["Python", "SQL", "ML"],
"address": {
"city": "New York",
"state": "NY"
}
}
with open("data.json", "w") as f:
json.dump(data, f, indent=2)
# Read JSON
with open("data.json", "r") as f:
loaded = json.load(f)
print(loaded["name"]) # Alice
print(loaded["skills"][0]) # Python
# JSON string conversion
json_string = json.dumps(data, indent=2)
print(json_string)
data_back = json.loads(json_string)File System Operations
python
import os
import shutil
from pathlib import Path
# Check file existence
print(os.path.exists("data.txt")) # True/False
print(os.path.isfile("data.txt")) # True if file
print(os.path.isdir("data")) # True if directory
# File information
print(os.path.getsize("data.txt")) # Size in bytes
print(os.path.basename("/path/to/file.txt")) # file.txt
print(os.path.dirname("/path/to/file.txt")) # /path/to
# Create directories
os.makedirs("path/to/dir", exist_ok=True)
# Rename/move
os.rename("old.txt", "new.txt")
# Delete
os.remove("file.txt") # Delete file
os.rmdir("empty_dir") # Delete empty directory
shutil.rmtree("dir_with_files") # Delete directory and contents
# List directory contents
for item in os.listdir("."):
print(item)
# Using pathlib (modern approach)
p = Path("data")
p.mkdir(parents=True, exist_ok=True)
for file in Path(".").glob("*.txt"):
print(f"{file.name}: {file.stat().st_size} bytes")The pathlib Module (Modern File Handling)
python
from pathlib import Path
# Create paths
home = Path.home()
project = Path("project")
config = project / "config" / "settings.json"
print(config) # project/config/settings.json
print(config.parent) # project/config
print(config.name) # settings.json
print(config.stem) # settings
print(config.suffix) # .json
# Read and write with pathlib
p = Path("example.txt")
p.write_text("Hello, World!")
content = p.read_text()
print(content) # Hello, World!
# Binary read/write
p.write_bytes(b"binary data")
data = p.read_bytes()
# Check existence
if p.exists():
print(f"Size: {p.stat().st_size} bytes")
# Iterate directory
for item in Path(".").iterdir():
if item.is_file():
print(f"File: {item.name}")
elif item.is_dir():
print(f"Dir: {item.name}/")
# Glob patterns
for py_file in Path(".").rglob("*.py"):
print(py_file)Exception Handling with Files
python
# Handle file errors gracefully
try:
with open("missing_file.txt", "r") as f:
content = f.read()
except FileNotFoundError:
print("File not found!")
except PermissionError:
print("Permission denied!")
except IOError as e:
print(f"IO error: {e}")Practical Example: Log File Analyzer
python
"""
Analyze a log file and generate a summary.
"""
from pathlib import Path
from collections import Counter
from datetime import datetime
def analyze_log(log_path):
"""Analyze a log file and return statistics."""
levels = Counter()
errors = []
line_count = 0
path = Path(log_path)
if not path.exists():
print(f"Log file not found: {log_path}")
return
with open(path, "r", encoding="utf-8") as f:
for line in f:
line_count += 1
line = line.strip()
# Count log levels
for level in ["ERROR", "WARNING", "INFO", "DEBUG"]:
if level in line:
levels[level] += 1
if level == "ERROR":
errors.append(line)
break
# Generate report
report = f"""
Log Analysis Report
{'=' * 40}
File: {log_path}
Total lines: {line_count}
Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}
Log Level Summary:
"""
for level, count in levels.most_common():
bar = "█" * (count * 2)
report += f" {level:<10} {count:>5} {bar}\n"
if errors:
report += f"\nErrors ({len(errors)}):\n"
for error in errors[:5]:
report += f" • {error[:80]}\n"
return reportSummary
- Always use
withstatements (context managers) for file handling - File modes:
"r"(read),"w"(write),"a"(append),"x"(create) - Reading:
read(),readline(),readlines(), or iterate directly - Writing:
write(),writelines(), orprint(file=f) - Use
csvmodule for CSV files andjsonmodule for JSON files pathlib.Pathis the modern, Pythonic way to handle file paths- Always handle FileNotFoundError and other IO exceptions
- Specify encoding (
utf-8) when working with text files
Next, we'll learn about Python modules and packages.