Of course! It looks like you're looking for a "JSON helper" in Python. This is a very common task, and Python's built-in json module is powerful, but we can create a more user-friendly helper class or set of functions to make working with JSON data even easier.

I'll provide you with a comprehensive solution:
- A
JSONHelperclass that wraps the standardjsonmodule, adding helpful features like pretty printing, safe file writing, and easy error handling. - A set of standalone utility functions for quick, common tasks.
- A complete, runnable example demonstrating how to use them.
The JSONHelper Class
This class is designed to be a robust and convenient wrapper around Python's json module. It handles file I/O and pretty-printing in a clean, object-oriented way.
import json
import os
from typing import Any, Dict, List, Optional
class JSONHelper:
"""
A helper class for easily reading, writing, and manipulating JSON files.
"""
def __init__(self, file_path: str):
"""
Initializes the JSONHelper with a specific file path.
Args:
file_path (str): The path to the JSON file.
"""
self.file_path = file_path
self._data: Optional[Dict | List] = None
def load(self) -> Dict | List:
"""
Loads data from the JSON file.
Returns:
dict | list: The parsed JSON data.
Raises:
FileNotFoundError: If the file does not exist.
json.JSONDecodeError: If the file contains invalid JSON.
"""
if not os.path.exists(self.file_path):
raise FileNotFoundError(f"JSON file not found at: {self.file_path}")
with open(self.file_path, 'r', encoding='utf-8') as f:
self._data = json.load(f)
return self._data
def get_data(self) -> Dict | List:
"""
Returns the currently loaded data. Loads it if not already loaded.
Returns:
dict | list: The loaded JSON data.
"""
if self._data is None:
self.load()
return self._data
def save(self, data: Optional[Dict | List] = None, indent: int = 4, sort_keys: bool = True) -> None:
"""
Saves data to the JSON file.
Args:
data (dict | list, optional): The data to save. If None, saves the currently loaded data.
indent (int, optional): The indentation level for pretty printing. Defaults to 4.
sort_keys (bool, optional): Whether to sort keys alphabetically. Defaults to True.
"""
if data is not None:
self._data = data
if self._data is None:
raise ValueError("No data to save. Provide data or load a file first.")
# Ensure the directory exists
os.makedirs(os.path.dirname(self.file_path), exist_ok=True)
with open(self.file_path, 'w', encoding='utf-8') as f:
json.dump(self._data, f, indent=indent, sort_keys=sort_keys, ensure_ascii=False)
print(f"Data successfully saved to {self.file_path}")
def pretty_print(self, data: Optional[Dict | List] = None) -> None:
"""
Pretty-prints JSON data to the console.
Args:
data (dict | list, optional): The data to print. If None, prints the currently loaded data.
"""
if data is not None:
print(json.dumps(data, indent=4, sort_keys=True, ensure_ascii=False))
elif self._data is not None:
print(json.dumps(self._data, indent=4, sort_keys=True, ensure_ascii=False))
else:
print("No data loaded or provided to print.")
def update(self, key_path: str, value: Any) -> None:
"""
Updates a value in the loaded JSON data using a dot-separated key path.
Example: 'user.address.city' will update data['user']['address']['city']
Args:
key_path (str): The dot-separated path to the key.
value (Any): The new value.
Raises:
ValueError: If data is not loaded.
KeyError: If a key in the path does not exist.
"""
if self._data is None:
self.load()
keys = key_path.split('.')
current_level = self._data
# Navigate to the parent of the target key
for key in keys[:-1]:
if key not in current_level:
raise KeyError(f"Key path '{key_path}' not found. Missing key: '{key}'")
current_level = current_level[key]
# Set the final value
final_key = keys[-1]
current_level[final_key] = value
print(f"Updated '{key_path}' to: {value}")
Standalone Utility Functions
Sometimes you just need a quick function without creating a class. Here are some common ones.
import json
import os
def load_json(file_path: str) -> dict | list:
"""Safely loads a JSON file and returns the data."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
print(f"Error: File not found at {file_path}")
return {}
except json.JSONDecodeError:
print(f"Error: Could not decode JSON from {file_path}")
return {}
def save_json(data: dict | list, file_path: str, indent: int = 4) -> bool:
"""Saves a Python object to a JSON file. Returns True on success, False on failure."""
try:
# Ensure the directory exists
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=indent, ensure_ascii=False)
return True
except Exception as e:
print(f"Error saving JSON to {file_path}: {e}")
return False
def pretty_print_json(data: dict | list) -> None:
"""Prints a Python object as a formatted JSON string."""
print(json.dumps(data, indent=4, sort_keys=True, ensure_ascii=False))
def safe_get(data: dict, key_path: str, default: Any = None) -> Any:
"""
Safely gets a nested value from a dictionary using a dot-separated path.
Returns a default value if the path is not found.
"""
keys = key_path.split('.')
current_level = data
try:
for key in keys:
current_level = current_level[key]
return current_level
except (KeyError, TypeError):
return default
Complete Example
Let's put everything together and see how it works. We'll create a sample JSON file, then use our helper to read, modify, and save it.

# --- Main execution block ---
if __name__ == "__main__":
# Define the file path for our example
JSON_FILE = "data/user_profile.json"
# --- 1. Create a sample JSON file to work with ---
sample_data = {
"username": "johndoe",
"email": "john.doe@example.com",
"is_active": True,
"age": 30,
"address": {
"street": "123 Python Lane",
"city": "Codeville",
"zip_code": "10101"
},
"tags": ["python", "developer", "json"]
}
# Use our utility function to create the initial file
save_json(sample_data, JSON_FILE)
print(f"Created sample file: {JSON_FILE}\n")
# --- 2. Using the JSONHelper Class ---
print("--- Using JSONHelper Class ---")
helper = JSONHelper(JSON_FILE)
# Load and pretty-print the data
data = helper.load()
print("Initial data loaded:")
helper.pretty_print()
# Update a value using the helper's update method
helper.update("age", 31)
helper.update("address.city", "New Tech City")
# Add a new tag
helper.update("tags", data["tags"] + ["helper"])
# Save the modified data
helper.save() # Uses the loaded data by default
# Pretty-print the final data
print("\nFinal data after modifications:")
helper.pretty_print()
# --- 3. Using Standalone Utility Functions ---
print("\n--- Using Standalone Utility Functions ---")
# Load the file again using the simple function
loaded_data = load_json(JSON_FILE)
print("Data loaded with load_json():")
pretty_print_json(loaded_data)
# Safely get a nested value
city = safe_get(loaded_data, "address.city")
print(f"\nUser's city (safe_get): {city}")
# Safely get a value that might not exist
country = safe_get(loaded_data, "address.country", "N/A")
print(f"User's country (safe_get with default): {country}")
# Clean up the created file
os.remove(JSON_FILE)
print(f"\nCleaned up and removed {JSON_FILE}")
How to Run the Example
- Save the entire code block above as a Python file (e.g.,
json_example.py). - Run it from your terminal:
python json_example.py
Expected Output
Created sample file: data/user_profile.json
--- Using JSONHelper Class ---
Initial data loaded:
{
"username": "johndoe",
"email": "john.doe@example.com",
"is_active": true,
"age": 30,
"address": {
"city": "Codeville",
"street": "123 Python Lane",
"zip_code": "10101"
},
"tags": [
"python",
"developer",
"json"
]
}
Updated 'age' to: 31
Updated 'address.city' to: New Tech City
Data successfully saved to data/user_profile.json
Final data after modifications:
{
"username": "johndoe",
"email": "john.doe@example.com",
"is_active": true,
"age": 31,
"address": {
"city": "New Tech City",
"street": "123 Python Lane",
"zip_code": "10101"
},
"tags": [
"python",
"developer",
"json",
"helper"
]
}
--- Using Standalone Utility Functions ---
Data loaded with load_json():
{
"username": "johndoe",
"email": "john.doe@example.com",
"is_active": true,
"age": 31,
"address": {
"city": "New Tech City",
"street": "123 Python Lane",
"zip_code": "10101"
},
"tags": [
"python",
"developer",
"json",
"helper"
]
}
User's city (safe_get): New Tech City
User's country (safe_get with default): N/A
Cleaned up and removed data/user_profile.json
This JSONHelper and the utility functions should cover most of your day-to-day JSON manipulation needs in Python in a clean, readable, and robust way.

