Python Basics — Working with JSON Files
Working with JSON Files
JSON (JavaScript Object Notation) is the most popular format for web APIs, configuration files, and data exchange. Python’s built-in json module handles it effortlessly.
Python ↔ JSON Type Mapping
| Python | JSON |
|---|---|
dict |
object {} |
list, tuple |
array [] |
str |
string "" |
int, float |
number |
True / False |
true / false |
None |
null |
Reading JSON Files — json.load()
import json
with open("config.json", "r") as f:
data = json.load(f)
print(type(data)) # <class 'dict'>
print(data["name"]) # Access like a normal Python dict
Sample config.json:
{
"name": "MyApp",
"version": "2.1.0",
"debug": false,
"features": ["auth", "logging", "cache"],
"database": {
"host": "localhost",
"port": 5432
}
}
Parsing JSON Strings — json.loads()
import json
json_string = '{"name": "Alice", "age": 30, "active": true}'
data = json.loads(json_string)
print(data["name"]) # Alice
print(data["active"]) # True (Python bool)
load()reads from a file,loads()reads from a string (the “s” stands for “string”).
Writing JSON Files — json.dump()
import json
config = {
"name": "MyApp",
"version": "2.1.0",
"debug": False,
"features": ["auth", "logging"],
}
with open("config.json", "w") as f:
json.dump(config, f)
Converting to JSON Strings — json.dumps()
import json
data = {"name": "Alice", "scores": [95, 87, 92]}
json_string = json.dumps(data)
print(json_string)
# {"name": "Alice", "scores": [95, 87, 92]}
Pretty-Printing JSON
import json
data = {
"users": [
{"name": "Alice", "role": "admin"},
{"name": "Bob", "role": "user"},
],
"settings": {"theme": "dark", "language": "en"},
}
# Pretty-print to string
pretty = json.dumps(data, indent=4)
print(pretty)
# Pretty-print to file
with open("output.json", "w") as f:
json.dump(data, f, indent=4)
Output:
{
"users": [
{
"name": "Alice",
"role": "admin"
},
{
"name": "Bob",
"role": "user"
}
],
"settings": {
"theme": "dark",
"language": "en"
}
}
Sorting Keys
import json
data = {"zebra": 1, "apple": 2, "mango": 3}
print(json.dumps(data, indent=2, sort_keys=True))
{
"apple": 2,
"mango": 3,
"zebra": 1
}
Working with API Response Data
import json
from urllib.request import urlopen
def fetch_user(user_id):
"""Fetch user data from a JSON API."""
url = f"https://jsonplaceholder.typicode.com/users/{user_id}"
with urlopen(url) as response:
data = json.loads(response.read().decode())
return data
user = fetch_user(1)
print(f"Name: {user['name']}")
print(f"Email: {user['email']}")
print(f"City: {user['address']['city']}")
Handling JSON Errors
import json
# Invalid JSON
bad_json = "{'name': 'Alice'}" # Single quotes are not valid JSON
try:
data = json.loads(bad_json)
except json.JSONDecodeError as e:
print(f"JSON Error: {e}")
# JSON Error: Expecting property name enclosed in double quotes
Common Patterns
Read, Modify, Write Back
import json
# Read
with open("settings.json", "r") as f:
settings = json.load(f)
# Modify
settings["theme"] = "dark"
settings["last_updated"] = "2025-03-03"
# Write back
with open("settings.json", "w") as f:
json.dump(settings, f, indent=4)
Default Values with .get()
import json
with open("config.json", "r") as f:
config = json.load(f)
# Safe access with defaults
debug = config.get("debug", False)
port = config.get("port", 8080)
name = config.get("name", "Unknown")
Handling Non-Serializable Types
import json
from datetime import datetime
data = {
"event": "login",
"timestamp": datetime.now(), # Not JSON-serializable!
}
# ❌ This fails:
# json.dumps(data) # TypeError: Object of type datetime is not JSON serializable
# ✅ Convert manually:
data["timestamp"] = data["timestamp"].isoformat()
print(json.dumps(data, indent=2))
# ✅ Or use a custom encoder:
class DateEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
data = {"event": "login", "timestamp": datetime.now()}
print(json.dumps(data, cls=DateEncoder, indent=2))
JSON Quick Reference
| Operation | Code |
|---|---|
| Read from file | json.load(f) |
| Parse from string | json.loads(s) |
| Write to file | json.dump(data, f) |
| Convert to string | json.dumps(data) |
| Pretty-print | json.dumps(data, indent=4) |
| Sort keys | json.dumps(data, sort_keys=True) |
| Handle errors | except json.JSONDecodeError |
Summary
json.load()/json.dump()work with filesjson.loads()/json.dumps()work with strings- Use
indent=4for human-readable output - Use
.get()for safe access with defaults - Handle
datetimeand other non-serializable types with custom encoders - Always wrap JSON parsing in
try/exceptfor untrusted data
Next up: File Handling Exercises →