JSON Serialization of Python Set
JSON (JavaScript Object Notation) is a concise, simple, uniform, and lightweight data interchange format widely used in web applications. Python, being a popular programming language, provides support for the JSON format.
It can convert Python objects into equivalent JSON objects and vice versa. However, JSON can only serialize limited data types and cannot handle set objects directly.
This poses a challenge for Python developers who want to exchange sets between different systems. In this article, we explore two ways to JSON serialize Python set, using jsonpickle module and custom JSON Encoder.
Using jsonpickle module to serialize Python set
The jsonpickle module is a third-party package that extends the built-in JSON module’s functionality and provides a way to serialize Python objects that are not JSON serializable. It converts custom Python objects to a JSON string that can be easily transmitted over a network or stored in a file.
Installing jsonpickle
To use jsonpickle, we need to install it first using pip, the Python package manager. In the command prompt, we can type the following command to install jsonpickle:
pip install jsonpickle
Encoding Python set to JSON using jsonpickle
Once we have installed jsonpickle, we can import it into our Python program and use it to encode a Python set object to a JSON string. Let’s consider the following example:
import jsonpickle
fruits_set = {"apple", "banana", "orange"}
json_str = jsonpickle.encode(fruits_set)
print(json_str)
Here, we define a Python set comprising of three fruits. We then use the jsonpickle.encode() function to convert this set into a JSON string and print it.
The output will look like this:
{"py/object": "builtins.set", "py/set": ["orange", "banana", "apple"]}
In the JSON string, the set object is represented by a dictionary containing two key-value pairs. The first key “py/object” specifies that it’s a Python object, and the second key “py/set” is a list of set elements.
Decoding JSON back to Python set using jsonpickle
We can also use jsonpickle to decode a JSON string back to its original Python set object. Let’s consider the following example:
import jsonpickle
json_str = '{"py/object": "builtins.set", "py/set": ["orange", "banana", "apple"]}'
fruits_set = jsonpickle.decode(json_str)
print(fruits_set)
Here, we define a JSON string that represents a Python set object. We then use the jsonpickle.decode() function to convert this JSON string into a set and print it.
The output will look like this:
{'orange', 'banana', 'apple'}
As we can see, the jsonpickle.decode() function has successfully converted the JSON string back to its original Python set object.
Using custom JSON Encoder to serialize Python set
In the previous section, we saw how we can use the jsonpickle module to serialize a Python set object to a JSON string and then deserialize it back to its original Python set object. In this section, we explore how we can use a custom JSON Encoder to serialize a Python set object.
A JSON Encoder is a Python object that takes a Python object and returns its equivalent JSON representation. The JSON module provides a JSONEncoder class that we can subclass and override its default() method to handle a Python set object.
Custom JSON Encoder
Let’s consider an example where we define a custom JSON Encoder that can handle Python set objects.
import json
class SetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
return json.JSONEncoder.default(self, obj)
fruits_set = {"apple", "banana", "orange"}
json_str = json.dumps(fruits_set, cls=SetEncoder)
print(json_str)
Here, we define a SetEncoder class that extends the JSONEncoder class. We override the default() method to check if the object is of type set, convert the set object to a list, and return it.
We then define a Python set comprising three fruits and use the json.dumps() function to convert this set to a JSON string using the SetEncoder class. Finally, we print the JSON string.
The output will look like this:
["orange", "banana", "apple"]
As we can see, the SetEncoder class has converted the Python set object to a JSON string by converting it to a list of elements.
Converting Python set to JSON using custom JSON Encoder
We can also use the SetEncoder class to serialize a Python set object to a JSON file. Let’s consider the following example:
import json
class SetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
return json.JSONEncoder.default(self, obj)
fruits_set = {"apple", "banana", "orange"}
with open("fruits.json", "w") as outfile:
json.dump(fruits_set, outfile, cls=SetEncoder)
Here, we define a SetEncoder class that extends the JSONEncoder class. We override the default() method to check if the object is of type set, convert the set object to a list, and return it.
We then define a Python set comprising three fruits and use the json.dump() function to convert this set to a JSON file using the SetEncoder class. Finally, we write the JSON string to a file named “fruits.json”.
Decoding JSON back to Python set using custom object hook
Now let’s consider an example of decoding a JSON file back to a Python set using a custom object hook.
import json
class customSetDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
super(customSetDecoder, self).__init__(
object_hook=self.object_hook,
*args, **kwargs
)
def object_hook(self, dct):
if isinstance(dct, dict) and "py/set" in dct:
return set(dct["py/set"])
return dct
with open("fruits.json", "r") as infile:
json_str = infile.read()
fruits_set = json.loads(json_str, cls=customSetDecoder)
print(fruits_set)
Here, we define a customSetDecoder class that extends the JSONDecoder class. We override the __init__() method to add a custom object_hook() function to the JSONDecoder constructor.
The object_hook() function checks if the dictionary has a key named “py/set”, indicating that it’s a Python set object. If “py/set” is present, it converts the list to a set and returns it.
Finally, we open the “fruits.json” file, read the JSON string, use json.loads() function with the customSetDecoder class to decode the JSON string back to a Python set object, and print it. The output will look like this:
{'orange', 'banana', 'apple'}
As we can see, the customSetDecoder class has successfully converted the JSON string back to its original Python set object.
Asking for feedback
We hope that this article has helped you understand how to JSON serialize Python set. If you have any feedback or comments, we would love to hear them.
Summary of topics covered
In this article, we explored two ways to JSON serialize Python set: using the jsonpickle module and a custom JSON Encoder. We discussed how to install jsonpickle, encode a Python set to a JSON string using jsonpickle.encode() function, decode a JSON string back to a Python set using jsonpickle.decode() function.
We also created a custom JSON Encoder that can handle Python set objects, demonstrated how to use it to convert a Python set object to a JSON string, and write it to a JSON file. Lastly, we explored how to decode a JSON string back to a Python set using a custom object hook.
Serializing Python set is a critical aspect of exchanging data between different systems, and the methods we have explored in this article can help Python developers overcome this challenge. By using either the jsonpickle module or a custom JSON Encoder, Python sets can be efficiently encoded and decoded as JSON strings.