Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make the Python json encoder support Python's new dataclasses

Starting with Python 3.7, there is something called a dataclass:

from dataclasses import dataclass  @dataclass class Foo:     x: str 

However, the following fails:

>>> import json >>> foo = Foo(x="bar") >>> json.dumps(foo) TypeError: Object of type Foo is not JSON serializable 

How can I make json.dumps() encode instances of Foo into json objects?

like image 640
miracle2k Avatar asked Jul 11 '18 13:07

miracle2k


People also ask

How do I create a new JSON file in Python?

To create a json file from an existing json file, open the existing file in read mode and read the content of that file and use the open() and with statement in write mode and dump the json data to a new json file.

How do you make a class JSON serializable in Python?

Use toJSON() Method to make class JSON serializable 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.

Does Python have native support for JSON?

Python Supports JSON Natively! Python comes with a built-in package called json for encoding and decoding JSON data.


2 Answers

Much like you can add support to the JSON encoder for datetime objects or Decimals, you can also provide a custom encoder subclass to serialize dataclasses:

import dataclasses, json  class EnhancedJSONEncoder(json.JSONEncoder):         def default(self, o):             if dataclasses.is_dataclass(o):                 return dataclasses.asdict(o)             return super().default(o)  json.dumps(foo, cls=EnhancedJSONEncoder) 
like image 126
miracle2k Avatar answered Oct 04 '22 09:10

miracle2k


Can't you just use the dataclasses.asdict() function to convert the dataclass to a dict? Something like:

>>> @dataclass ... class Foo: ...     a: int ...     b: int ...      >>> x = Foo(1,2) >>> json.dumps(dataclasses.asdict(x)) '{"a": 1, "b": 2}' 
like image 27
Chuck Wooters Avatar answered Oct 04 '22 09:10

Chuck Wooters