Borislav Hadzhiev
Last updated: Apr 20, 2022
Photo from Unsplash
The Python "TypeError: Object of type int32 is not JSON serializable" occurs
when we try to convert a numpy int32 object to a JSON string. To solve the
error, convert the numpy int to a Python integer before converting it to JSON,
e.g. int(my_numpy_int)
.
Here is an example of how the error occurs.
import json import numpy as np salary = np.power(50, 2, dtype=np.int32) # ⛔️ TypeError: Object of type int32 is not JSON serializable json_str = json.dumps({'salary': salary})
We tried passing a numpy int32 object to the json.dumps()
method but the
method doesn't handle numpy integers by default.
To solve the error, use the built-in int()
(or float
) constructor to convert
the numpy int32 object to a native Python integer before serializing it.
import json import numpy as np salary = np.power(50, 2, dtype=np.int32) # ✅ convert to Python native int json_str = json.dumps({'salary': int(salary)}) print(json_str) # 👉️ '{"salary": 2500}' print(type(json_str)) # 👉️ <class 'str'>
The default JSON encoder handles int
and float
values, so we can use a
native Python int
instead of a numpy int32 when serializing to JSON.
The json.dumps method converts a Python object to a JSON formatted string.
Alternatively, you can extend from the JSONEncoder
class and handle the
conversions in a default
method.
import json import numpy as np class NpEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.integer): return int(obj) if isinstance(obj, np.floating): return float(obj) if isinstance(obj, np.ndarray): return obj.tolist() return json.JSONEncoder.default(self, obj) salary = np.power(50, 2, dtype=np.int32) json_str = json.dumps({'salary': salary}, cls=NpEncoder) print(json_str) # 👉️ {"salary": 2500} print(type(json_str)) # 👉️ <class 'str'>
We extended from the JSONEncoder class.
The JSONEncoder
class supports the following objects and types by default.
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float, int and float derived Enums | number |
True | true |
False | false |
None | null |
Notice that the JSONEncoder
class doesn't support numpy int32 to JSON
conversion by default.
We can handle this by extending from the class and implementing a default()
method that returns a serializable object.
import json import numpy as np class NpEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.integer): return int(obj) if isinstance(obj, np.floating): return float(obj) if isinstance(obj, np.ndarray): return obj.tolist() return json.JSONEncoder.default(self, obj)
If the passed in object is an instance of np.integer
, we convert the object to
a Python int
and return the result.
If the passed in object is an instance of np.floating
, we convert it to a
Python float
and return the result.
If the object is an instance of np.ndarray
, we convert it to a Python list
and return the result.
In all other cases, we let the base classes' default method do the serialization.
To use a custom JSONEncoder
, specify it with the cls
keyword argument in
your call to the json.dumps()
method.
import json import numpy as np class NpEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, np.integer): return int(obj) if isinstance(obj, np.floating): return float(obj) if isinstance(obj, np.ndarray): return obj.tolist() return json.JSONEncoder.default(self, obj) salary = np.power(50, 2, dtype=np.int32) # ✅ provide cls keyword argument json_str = json.dumps({'salary': salary}, cls=NpEncoder) print(json_str) # 👉️ {"salary": 2500} print(type(json_str)) # 👉️ <class 'str'>
If you don't provide the cls
kwarg, the default JSONEncoder
is used.