Borislav Hadzhiev
Last updated: Apr 20, 2022
Check out my new book
The Python "TypeError: Object of type set is not JSON serializable" occurs
when we try to convert a set
object to a JSON string. To solve the error,
convert the set
to a list before serializing it to JSON, e.g.
json.dumps(list(my_set))
.
Here is an example of how the error occurs.
import json my_set = {'a', 'b', 'c', 'd'} # ⛔️ TypeError: Object of type set is not JSON serializable json_str = json.dumps(my_set)
We tried passing a set
object to the json.dumps()
method but the method
doesn't handle set
objects by default
To solve the error, use the built-in list()
class to convert he set
to a
list
before serializing it.
import json my_set = {'a', 'b', 'c', 'd'} json_str = json.dumps(list(my_set)) print(json_str) # '["b", "c", "a", "d"]' print(type(json_str)) # <class 'str'>
The default JSON encoder handles list
values, so we can use a native Python
list
instead of a set
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 class SetEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, set): return list(obj) return json.JSONEncoder.default(self, obj) my_set = {'a', 'b', 'c', 'd'} json_str = json.dumps(my_set, cls=SetEncoder) print(json_str) # 👉️ '["b", "c", "a", "d"]' 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 set
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 class SetEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, set): return list(obj) return json.JSONEncoder.default(self, obj)
If the passed in value is a set
, we convert it to a list
and return the
result.
The isinstance
function returns True
if the passed in object is an instance or a subclass of
the passed in class.
To use a custom JSONEncoder
, specify it with the cls
keyword argument in
your call to the json.dumps()
method.
import json class SetEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, set): return list(obj) return json.JSONEncoder.default(self, obj) my_set = {'a', 'b', 'c', 'd'} # ✅ pass cls keyword argument json_str = json.dumps(my_set, cls=SetEncoder) print(json_str) # 👉️ '["b", "c", "a", "d"]' print(type(json_str)) # 👉️ <class 'str'>
If you don't provide the cls
kwarg, the default JSONEncoder
is used.