Customize JSON Array Decoding with array_hook in Python 3.15

Customize JSON Array Decoding with array_hook in Python 3.15

Decoding JSON produces Python objects chosen by the json module, and every JSON array becomes a list. That is a reasonable default, but a list is mutable and therefore cannot be hashed. A decoded array cannot be used as a dictionary key, stored in a set, or combined into a cache key without first being converted.

For example, a document describing a point decodes its coordinates as nested lists:

import json

data = json.loads('{"name":"point","coords":[[1,2],[3,4]]}')

print(data)  # {'name': 'point', 'coords': [[1, 2], [3, 4]]}
print(type(data['coords']).__name__)  # list

Converting the lists afterwards means walking the structure and rebuilding every array it contains, including the nested ones.

Since Python 3.15, the array_hook parameter controls how arrays are turned into Python objects.

import json

data = json.loads('{"name":"point","coords":[[1,2],[3,4]]}', array_hook=tuple)

print(data)  # {'name': 'point', 'coords': ((1, 2), (3, 4))}
print(type(data['coords']).__name__)  # tuple

The hook runs for every array in the document, so the two inner arrays become tuples as well as the outer one. The conversion happens while the document is being parsed, which removes the separate pass over the result.

The parameter accepts any callable, not only tuple. Passing frozenset produces sets of values instead, and a custom class gives every array a type of its own. The parameter is available on json.load, json.loads and the json.JSONDecoder constructor, so it works for both string and file input, and for decoders that are created once and reused.

Leave a Comment

Cancel reply

Your email address will not be published.