JSON Module
JSON (JavaScript Object Notation) is the universal language of data exchange on the
web. APIs return JSON, configuration files use JSON, and databases store JSON. Python's built-in
json module makes it easy to parse JSON strings into Python dictionaries, convert
Python objects to JSON, and read/write JSON files. If you're building web applications, working
with APIs, or handling configuration data - JSON mastery is essential!
Parsing JSON (String to Python)
Use json.loads() ("load string") to parse a JSON string into a Python object.
JSON objects become Python dictionaries, arrays become lists, and JSON's true,
false, and null become Python's True, False,
and None.
Click Run to execute your code
JSON object
{} โ Python dictJSON array
[] โ Python listJSON string โ Python
strJSON number โ Python
int or floatJSON
true/false โ Python True/FalseJSON
null โ Python None
Converting Python to JSON
Use json.dumps() ("dump string") to convert Python objects to a JSON string.
Most Python types convert naturally: dictionaries become objects, lists/tuples become arrays,
and booleans/None convert to their JSON equivalents. Some types (like sets and datetime) require
custom handling.
Click Run to execute your code
loads() and dumps()
work with strings (the 's' stands for string). load() and
dump() (without 's') work with files. This naming convention
helps you remember which function to use!
Reading and Writing JSON Files
Use json.load() to read JSON from a file and json.dump() to write
JSON to a file. These work directly with file objects, making it easy to persist data or
read configuration files. Always use the with statement to ensure proper file handling.
Click Run to execute your code
json.loads() is safer than eval(), malformed JSON can still
cause errors. Wrap parsing in try/except blocks:
try: data = json.loads(text) except json.JSONDecodeError: handle_error()
Formatting and Pretty Printing
By default, json.dumps() produces compact output. For human-readable output, use
indent for pretty printing and sort_keys for consistent key ordering.
These options are invaluable for debugging, logging, and configuration files.
Click Run to execute your code
Common Mistakes
1. Confusing loads/dumps with load/dump
import json
# Wrong - loads expects a string, not a file!
with open("data.json") as f:
data = json.loads(f) # TypeError!
# Correct - use load (no 's') for files
with open("data.json") as f:
data = json.load(f)
# Wrong - dumps returns a string, doesn't write to file
with open("out.json", "w") as f:
json.dumps(data, f) # Just returns string, ignores f!
# Correct - use dump (no 's') for files
with open("out.json", "w") as f:
json.dump(data, f)
2. Using single quotes in JSON strings
import json
# Wrong - JSON requires double quotes!
bad_json = "{'name': 'Alice'}"
data = json.loads(bad_json) # JSONDecodeError!
# Correct - use double quotes
good_json = '{"name": "Alice"}'
data = json.loads(good_json) # Works!
# Tip: Use triple quotes for multiline JSON
json_str = """
{
"name": "Alice",
"age": 30
}
"""
3. Trying to serialize non-JSON types
import json
from datetime import datetime
# Wrong - sets and datetime aren't JSON serializable!
data = {
"tags": {"python", "json"}, # set
"created": datetime.now() # datetime
}
json.dumps(data) # TypeError!
# Fix 1: Convert to serializable types
data = {
"tags": list({"python", "json"}),
"created": datetime.now().isoformat()
}
# Fix 2: Use custom encoder
def custom_encoder(obj):
if isinstance(obj, set):
return list(obj)
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Not serializable: {type(obj)}")
json.dumps(data, default=custom_encoder)
4. Not handling JSONDecodeError
import json
# Wrong - crashes on invalid JSON
user_input = "not valid json"
data = json.loads(user_input) # JSONDecodeError!
# Correct - handle the error
try:
data = json.loads(user_input)
except json.JSONDecodeError as e:
print(f"Invalid JSON: {e}")
data = {} # Default value
5. Forgetting to specify encoding for non-ASCII
import json
# Unicode characters
data = {"name": "Caf\u00e9", "city": "Z\u00fcrich"}
# Default - escapes non-ASCII (safe but ugly)
print(json.dumps(data))
# {"name": "Caf\u00e9", "city": "Z\u00fcrich"}
# Better for readability - preserve unicode
print(json.dumps(data, ensure_ascii=False))
# {"name": "Caf", "city": "Zrich"}
# When writing files - specify encoding!
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False)
Exercise: Configuration Manager
Task: Create functions to manage application configuration stored as JSON.
Requirements:
- Create a function to load config from a JSON string
- Create a function to get a config value with a default
- Create a function to update config and return the JSON string
- Handle missing keys gracefully
Click Run to execute your code
Show Solution
import json
def load_config(json_string):
"""Load configuration from JSON string."""
try:
return json.loads(json_string)
except json.JSONDecodeError:
return {}
def get_config_value(config, key, default=None):
"""Get a configuration value with optional default."""
return config.get(key, default)
def update_config(config, key, value):
"""Update config and return as formatted JSON string."""
config[key] = value
return json.dumps(config, indent=2)
# Test the functions
config_json = '{"theme": "dark", "font_size": 14}'
# Load
config = load_config(config_json)
print(f"Loaded: {config}")
# Get values
theme = get_config_value(config, "theme", "light")
language = get_config_value(config, "language", "en")
print(f"Theme: {theme}")
print(f"Language: {language}")
# Update
new_json = update_config(config, "notifications", True)
print(f"Updated config:\n{new_json}")
Summary
- Parse string:
json.loads(json_string)- JSON string to Python - Encode to string:
json.dumps(python_obj)- Python to JSON string - Read file:
json.load(file_object)- file to Python - Write file:
json.dump(python_obj, file_object)- Python to file - Pretty print:
json.dumps(data, indent=2) - Sort keys:
json.dumps(data, sort_keys=True) - Custom types:
json.dumps(data, default=encoder_func) - Error handling: Catch
json.JSONDecodeErrorfor invalid JSON
What's Next?
Now that you can work with JSON data, let's learn about Regular Expressions (RegEx) - the powerful pattern matching language for searching, validating, and manipulating text. RegEx is essential for data validation, text processing, and parsing complex string patterns!
Enjoying these tutorials?