Python JSON

The json module in Python provides methods to work with JSON (JavaScript Object Notation) data. JSON is widely used for data exchange due to its readability and compatibility across platforms. Python's json module supports parsing JSON data and serializing Python objects into JSON.

1. Basic JSON Encoding (Serialization)

Use json.dumps() to convert a Python object into a JSON-formatted string.
import json

# Define a Python dictionary
data = {
    "name": "Alice",
    "age": 25,
    "is_student": False,
    "courses": ["Math", "Science"]
}

# Convert the dictionary to a JSON string
json_string = json.dumps(data)
print("JSON string:", json_string)

Output:

JSON string: {"name": "Alice", "age": 25, "is_student": false, "courses": ["Math", "Science"]}
Explanation: json.dumps() serializes the Python dictionary into a JSON-formatted string. Booleans are converted to lowercase (False to false), and Python lists become JSON arrays.

2. Writing JSON to a File

Use json.dump() to write a JSON object directly to a file.
# Write JSON data to a file
with open("data.json", "w") as json_file:
    json.dump(data, json_file)
print("JSON data written to file 'data.json'")

Output:

JSON data written to file 'data.json'
Explanation: json.dump() writes JSON data to a file. This method is useful when you need to save data for later use.

3. Loading JSON from a String (Deserialization)

Use json.loads() to parse a JSON string into a Python object.
# JSON string to parse
json_data = '{"name": "Bob", "age": 30, "is_student": true, "courses": ["History", "Physics"]}'

# Convert JSON string to a Python dictionary
data_dict = json.loads(json_data)
print("Parsed data:", data_dict)

Output:

Parsed data: {'name': 'Bob', 'age': 30, 'is_student': True, 'courses': ['History', 'Physics']}
Explanation: json.loads() parses a JSON-formatted string and converts it into a Python dictionary.

4. Reading JSON from a File

Use json.load() to load JSON data directly from a file.
# Read JSON data from a file
with open("data.json", "r") as json_file:
    data_from_file = json.load(json_file)
print("Data from file:", data_from_file)

Output:

Data from file: {'name': 'Alice', 'age': 25, 'is_student': False, 'courses': ['Math', 'Science']}
Explanation: json.load() reads JSON data from a file and parses it into a Python object.

5. Customizing JSON Formatting

Use indent, separators, and sort_keys arguments in json.dumps() for readable JSON output.
# Pretty-print JSON with indentation, sorted keys, and custom separators
pretty_json = json.dumps(data, indent=4, separators=(",", ": "), sort_keys=True)
print("Pretty JSON:\n", pretty_json)

Output:

Pretty JSON:
{
    "age": 25,
    "courses": [
        "Math",
        "Science"
    ],
    "is_student": false,
    "name": "Alice"
}
Explanation: Indentation and separators make JSON more readable. Sorting keys organizes data by key names.

6. JSON Encoding Custom Data Types

Python's json module does not support custom objects by default. Implement a custom encoder by subclassing json.JSONEncoder.
from datetime import datetime

# Custom object
class User:
    def __init__(self, name, signup_date):
        self.name = name
        self.signup_date = signup_date

# Custom encoder for User
class UserEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, User):
            return {"name": obj.name, "signup_date": obj.signup_date.isoformat()}
        return super().default(obj)

# Example usage
user = User("Alice", datetime.now())
user_json = json.dumps(user, cls=UserEncoder)
print("Custom encoded JSON:", user_json)

Output:

Custom encoded JSON: {"name": "Alice", "signup_date": "2024-10-30T10:20:30"}
Explanation: The UserEncoder class defines how to serialize a User object into JSON, handling the datetime as a formatted string.

7. Decoding Custom JSON Data Types

To decode custom objects, provide a custom function to json.loads() via the object_hook argument.
# Custom decoding function
def user_decoder(dct):
    if "signup_date" in dct:
        dct["signup_date"] = datetime.fromisoformat(dct["signup_date"])
    return dct

# Decode JSON with custom object_hook
decoded_user = json.loads(user_json, object_hook=user_decoder)
print("Decoded user:", decoded_user)

Output:

Decoded user: {'name': 'Alice', 'signup_date': datetime.datetime(2024, 10, 30, 10, 20, 30)}
Explanation: The object_hook function transforms date strings back into datetime objects.

8. Handling Errors with JSON

When working with potentially malformed JSON data, json.JSONDecodeError catches parsing errors.
# Malformed JSON string
bad_json = '{"name": "Alice", "age": 25, }'

# Try parsing and catch JSONDecodeError
try:
    data = json.loads(bad_json)
except json.JSONDecodeError as e:
    print("Error decoding JSON:", e)

Output:

Error decoding JSON: Expecting property name enclosed in double quotes: line 1 column 23 (char 22)
Explanation: json.JSONDecodeError is raised when JSON data cannot be parsed due to syntax errors.

9. Converting JSON to and from Other Types

Use json.dumps() and json.loads() to convert various types, but note that only certain types (dictionaries, lists, strings, numbers, booleans, and None) can be converted directly.
# Convert a tuple to JSON
try:
    json_data = json.dumps(("apple", "banana"))
except TypeError as e:
    print("Error:", e)

# Convert a valid dictionary with simple types
valid_data = json.dumps({"fruits": ["apple", "banana"]})
print("Valid JSON data:", valid_data)

Output:

Error: Object of type tuple is not JSON serializable
Valid JSON data: {"fruits": ["apple", "banana"]}
Explanation: Only JSON-compatible data types can be serialized directly. Tuples require conversion to lists.

Summary

The json module provides robust support for handling JSON in Python, including serializing and deserializing data, custom encoding and decoding, and error handling, making it versatile for a range of JSON-related tasks.

Previous: Python sys module | Next: Python Regular Expressions

<
>