This error occurs when you try to serialize a Decimal object to a JSON string using the json.dumps()
method. You can solve this error by setting the default keyword argument to str
when calling the json.dumps()
method. For example,
json_str = json.dumps(decimal_value, default=str)
You can also define a function that converts the Decimal
object to a string and set the default keyword argument to the name of that function.
This tutorial will go through how to solve the error with code examples.
Table of contents
TypeError: Object of type Decimal is not JSON serializable
Let’s break up the error message to understand what the error means. TypeError occurs whenever you attempt to use an illegal operation for a specific data type. The part “Object of type Decimal” tells us the error is due to an illegal operation with a Decimal
object.
Serialization in Python refers to converting a Python object into a transmittable format that we can recreate when needed using deserialization. JSON serialization returns a human-readable string form called a JSON string. The JSON encoder json.dump() and json.dumps() can only serialize certain object types like dictionaries, lists, or strings.
“is not JSON serializable” informs us that the JSON serialization is an illegal operation for the Decimal
type.
Example
Let’s look at an example of JSON serializing a Decimal
object. First, we will import the classes from the decimal module and then create a Decimal
object containing Euler’s number.
import json from decimal import * euler_num = Decimal('2.71828')
Next, we will attempt to serialize the Decimal
object using json.dumps()
.
json_str = json.dumps(euler_num) print(json_str)
Let’s run the code to see what happens:
TypeError: Object of type Decimal is not JSON serializable
The error occurs because euler_num
is an object of type Decimal
and cannot be serialized into a JSON string.
Solution #1: Set default to str
The simplest way to solve this error is to set the default
keyword argument of the json.dumps()
method to the str
class. The default value for the keyword argument default
is None
. We can set default
to a function that gets called for objects that are not serializable. When we set the default
keyword argument to str
, it converts the Decimal object to a string.
Let’s look at the updated code:
import json from decimal import * euler_num = Decimal('2.71828') json_str = json.dumps(euler_num, default=str) print(json_str)
Let’s run the code to see the JSON string:
"2.71828"
Solution #2: Define a custom function for default kwarg
We can also solve this error by defining a custom function that converts a Decimal
object to a string. Let’s look at the custom function:
from datetime import datetime, date import json def serialize_decimal(obj): if isinstance(obj, Decimal): return str(obj) raise TypeError ("Type %s is not serializable" % type(obj))
Note that if the object obj
is not an instance of Decimal
the function will raise a TypeError. Let’s set the default
keyword argument to our custom function and run the code:
euler_num = Decimal('2.71828') json_str = json.dumps(euler_num, default=serialize_decimal) print(json_str)
"2.71828"
Solution #3: Define a JSONEncoder subclass for the cls kwarg
We can also solve this error by building a custom JSONEncoder
subclass. This subclass will override the default method to serialize additional types.
from decimal import * import json class decimal_encoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, Decimal): return str(obj) return json.JSONEncoder.default(self, obj)
Similar to the custom function, the default
method of the decimal_encoder
class checks if the object is of type Decimal
, converts it to a string and returns it.
We have to specify the custom JSONEncoder subclass with the cls
keyword argument. Otherwise, JSONEncoder is used. Let’s look at the updated code:
euler_num = Decimal('2.71828') json_str = json.dumps(euler_num, cls=decimal_encoder) print(json_str)
Let’s run the code to see the result:
"2.71828"
Below is the collection of objects that the JSONEncoder
class supports and their JSON
equivalent.
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str | string |
int, float, int- & float- derived Enums | number |
True | true |
False | false |
None | null |
What is Python Decimal?
The Python decimal model provides support for fast correctly-rounded decimal floating-point arithmetic. Decimal objects have higher precision than floating-point numbers, making them particularly useful for financial calculations.
Summary
Congratulations on reading to the end of this tutorial.
For further reading on errors involving JSON serialization, go to the articles:
- How to Solve Python TypeError: Object of type int32 is not JSON serializable
- How to Solve Python TypeError: Object of type Decimal is not JSON serializable
- How to Solve Python TypeError: Object of type DataFrame is not JSON serializable
- How to Solve Python TypeError: Object of type map is not JSON serializable
Go to the online courses page on Python to learn more about Python for data science and machine learning.
Have fun and happy researching!
Suf is a senior advisor in data science with deep expertise in Natural Language Processing, Complex Networks, and Anomaly Detection. Formerly a postdoctoral research fellow, he applied advanced physics techniques to tackle real-world, data-heavy industry challenges. Before that, he was a particle physicist at the ATLAS Experiment of the Large Hadron Collider. Now, he’s focused on bringing more fun and curiosity to the world of science and research online.