Python json serializable objects

Make a Python Class JSON Serializable

You are here because when you try to encode a custom Python object into a JSON format, you received a TypeError: Object of type SampleClass is not JSON serializable . In this article, I will show you how to serialize arbitrary Python objects to JSON so that you can convert any custom Python objects into JSON formatted data.

The built-in json module of Python can only handle Python primitives types that have a direct JSON equivalent. i.e., The fundamental problem is that the JSON encoder json.dump() and json.dumps() only knows how to serialize the basic set of object types by default (e.g., dictionary, lists, strings, numbers, None, etc.). To solve this, we need to build a custom encoder to make our Class JSON serializable.

There are multiple ways to Make a Python Class JSON Serializable. You can pick the one which best suited to your problem complexity. Let’ understand each one-by-one.

Further Reading:

Goals of this lesson:

  • Write your own custom JSON Encoder to make class JSON serializable
  • Create custom toJSON() Method to make Python class JSON serializable
  • Use jsonpickle module to make class JSON serializable
  • How to Inherit class from dict to make class JSON serializable
Читайте также:  Sign Up Page

Explained how to make Python class JSON serializable

Write custom JSONEncoder to make class JSON serializable

Python json module has a JSONEncoder class. You can extend it If you want more customized output. i.e., you will have to subclass JSONEncoder so you can implement your custom JSON serialization.

The json.dump() and json.dumps() method of the JSON module has a cls kwarg. Using this argument, you can pass a custom JSON Encoder, which tells json.dump() or json.dumps() method how to encode your object into JSON formatted data. The default JSONEncoder class has a default() method that will be used when we execute JSONEncoder.encode(object) . This method converts only basic types into JSON.

Your custom JSONEncoder subclass will override the default() method to serialize additional types. Specify it with the cls kwarg in json.dumps() method; otherwise, default JSONEncoder is used. Example: json.dumps(cls=CustomEncoder) . Let’s see the example now.

import json from json import JSONEncoder class Employee: def __init__(self, name, salary, address): self.name = name self.salary = salary self.address = address class Address: def __init__(self, city, street, pin): self.city = city self.street = street self.pin = pin # subclass JSONEncoder class EmployeeEncoder(JSONEncoder): def default(self, o): return o.__dict__ address = Address("Alpharetta", "7258 Spring Street", "30004") employee = Employee("John", 9000, address) print("Printing to check how it will look like") print(EmployeeEncoder().encode(employee)) print("Encode Employee Object into JSON formatted Data using custom JSONEncoder") employeeJSONData = json.dumps(employee, indent=4, cls=EmployeeEncoder) print(employeeJSONData) # Let's load it using the load method to check if we can decode it or not. print("Decode JSON formatted Data") employeeJSON = json.loads(employeeJSONData) print(employeeJSON)
Printing to check how it will look like > Encode Object into JSON formatted Data using custom JSONEncoder < "name": "John", "salary": 9000, "address": < "city": "Alpharetta", "street": "7258 Spring Street", "pin": "30004" >> Decode JSON formatted Data >
  • The EmployeeEncoder class overrides the default() method of a JSONEncoder class, so we able to convert custom Python object into JSON.
  • In EmployeeEncoder class we converted our Object into a Python dictionary format.

Note: Refer to decode JSON into the Custom Python Object instead of a dictionary if you also want to decode JSON back to the Custom Python Object.

Use toJSON() Method to make class JSON serializable

A simple and straightforward solution. Instead of making class JSON serializable, we can implement a serializer method in the class.
So we don’t need to write custom JSONEncoder.

This new toJSON() serializer method will return the JSON representation of the Object. i.e., It will convert custom Python Object to JSON string. Let’ see the example.

import json class Employee: def __init__(self, name, salary, address): self.name = name self.salary = salary self.address = address def toJson(self): return json.dumps(self, default=lambda o: o.__dict__) class Address: def __init__(self, city, street, pin): self.city = city self.street = street self.pin = pin address = Address("Alpharetta", "7258 Spring Street", "30004") employee = Employee("John", 9000, address) print("Encode into JSON formatted Data") employeeJSONData = json.dumps(employee.toJson(), indent=4) print(employeeJSONData) # Let's load it using the load method to check if we can decode it or not. print("Decode JSON formatted Data") employeeJSON = json.loads(employeeJSONData) print(employeeJSON)
Encode into JSON formatted Data ">" Decode JSON formatted Data >
  • As you can see we are able to encode and decode Employee object into JSON formatted stream.
  • We used the use default argument of json.dumps() method to serialize additional types to dict and converted newly created dict to JSON string.

Note: Refer to decode JSON into the Custom Python Object instead of a dictionary if you also want to decode JSON back to the Custom Python Object.

Use the jsonpickle module to make class JSON serializable

jsonpickle is a Python library designed to work with complex Python Objects. You can use jsonpickle for serialization complex Python objects into JSON. Also, and deserialization from JSON to complex Python objects.

As you know The built-in json module of Python can only handle Python primitives types that have a direct JSON equivalent (e.g., dictionary, lists, strings, Numbers, None, etc.).

jsonpickle builds on top of these libraries and allows more complex data structures to be serialized to JSON. jsonpickle is highly configurable and extendable–allowing the user to choose the JSON backend and add additional backends.

  • Install jsonpickle using pip install jsonpickle
  • Execute jsonpickle.encode(object) to serialize custom Python Object.

You can refer to Jsonpickle Documentation for more detail. Let’s see the jsonpickle example to make a Python class JSON serializable.

import json import jsonpickle from json import JSONEncoder class Employee(object): def __init__(self, name, salary, address): self.name = name self.salary = salary self.address = address class Address(object): def __init__(self, city, street, pin): self.city = city self.street = street self.pin = pin address = Address("Alpharetta", "7258 Spring Street", "30004") employee = Employee("John", 9000, address) print("Encode Object into JSON formatted Data using jsonpickle") empJSON = jsonpickle.encode(employee, unpicklable=False) print("Writing JSON Encode data into Python String") employeeJSONData = json.dumps(empJSON, indent=4) print(employeeJSONData) print("Decode JSON formatted Data using jsonpickle") EmployeeJSON = jsonpickle.decode(employeeJSONData) print(EmployeeJSON) # Let's load it using the load method to check if we can decode it or not. print("Load JSON using loads() method") employeeJSON = json.loads(EmployeeJSON) print(employeeJSON)
Encode Object into JSON formatted Data using jsonpickle Writing JSON Encode data into Python String ", \"name\": \"John\", \"salary\": 9000>" Decode JSON formatted Data using jsonpickle , "name": "John", "salary": 9000> Load JSON using loads() method , 'name': 'John', 'salary': 9000>

I used unpicklable=False because I don’t want to decode this data back to Object. If you wish to decode JSON back to Employee Object use unpicklable=True . or please refer to load JSON data directly into Object. There I mentioned how to use jsonpickle to load JSON data directly into Object.

Also, you can try the jsons module to make class JSON serializable.

Inheriting from dict to make class JSON serializable

If you don’t want to write a custom encoder, also, if you are not willing to use jsonpickle, you can use this solution. Check if this solution works for you. This solution works if your Class is not complicated. For trickier things, you will have to set keys explicitly.

This method is useful for those who cannot modify their json.dumps(obj) call to include custom encoder. i.e. If you want to call json.dumps(obj) as-is, then a simple solution is inheriting from dict.

So, in this case, you don’t need to change the call to json.dumps() . I mean, what if you are passing an object and JSON dumping is happening inside different application components or framework where you don’t have control to modify json.dumps() call.

import json class Employee(dict): def __init__(self, name, age, salary, address): dict.__init__(self, name=name, age=age, salary=salary, address=address) class Address(dict): def __init__(self, city, street, pin): dict.__init__(self, city=city, street=street, pin=pin) address = Address("Alpharetta", "7258 Spring Street", "30004") employee = Employee("John", 36, 9000, address) print("Encode into JSON formatted Data") employeeJSON = json.dumps(employee) print(employeeJSON) # Let's load it using the load method to check if we can decode it or not. print("Decode JSON formatted Data") employeeJSONData = json.loads(employeeJSON) print(employeeJSONData)
Encode into JSON formatted Data > Decode JSON formatted Data >

Next Steps

I want to hear from you. What do you think of this article? Or maybe I missed one of the ways to make Python Class JSON serializable. Either way, let me know by leaving a comment below.

Also, try to solve the Python JSON Exercise to have a better understanding of Working with JSON Data in Python.

Did you find this page helpful? Let others know about it. Sharing helps me continue to create free Python resources.

About Vishal

I’m Vishal Hule, Founder of PYnative.com. I am a Python developer, and I love to write articles to help students, developers, and learners. Follow me on Twitter

Python Exercises and Quizzes

Free coding exercises and quizzes cover Python basics, data structure, data analytics, and more.

  • 15+ Topic-specific Exercises and Quizzes
  • Each Exercise contains 10 questions
  • Each Quiz contains 12-15 MCQ

Источник

Сериализация и десериализация объектов Python: часть 1

Gigi Sayfan

Gigi Sayfan Last updated May 26, 2022

Сериализация и десериализация объектов Python является важным аспектом любой нетривиальной программы. Если в Python вы сохраняете что-то в файле, если вы читаете файл конфигурации или отвечаете на HTTP-запрос, вы выполняете сериализацию и десериализацию объектов.

В некотором смысле, сериализация и десериализация — самые скучные вещи в мире. Кто заботится обо всех форматах и протоколах? Вы просто хотите сохранить или стримить некоторые объекты Python и вернуть их позже.

Это очень здоровый способ взглянуть на мир на концептуальном уровне. Но на прагматическом уровне, какая схема сериализации, формат или протокол, которые вы выбираете, могут определять, насколько быстро работает ваша программа, насколько она безопасна, насколько свободно вы должны поддерживать свое состояние и насколько хорошо вы собираетесь взаимодействовать с другими системы.

Причина в том, что существует так много вариантов, что разные обстоятельства требуют разных решений. Нет серебренной поли. В этом учебнике из двух частей я расскажу о преимуществах и недостатках самых успешных схем сериализации и десериализации, покажу, как их использовать, и дам рекомендации по выбору между ними, когда вы сталкиваетесь с конкретным вариантом использования.

Пример выполнения

В следующих разделах я буду сериализовать и десериализовать одни и те же графы объектов Python, используя различные сериализаторы. Чтобы избежать повторения, я определяю эти графы объектов здесь.

Простой Graph объект

Простой graph объект — это словарь, который содержит список целых чисел, строку, float, логическое и None.

simple = dict(int_list=[1, 2, 3], 

Источник

Оцените статью