I have a Decimal('3.9')
as part of an object, and wish to encode this to a JSON string which should look like {'x': 3.9}
. I don't care about precision on the client side, so a float is fine.
Is there a good way to serialize this? JSONDecoder doesn't accept Decimal objects, and converting to a float beforehand yields {'x': 3.8999999999999999}
which is wrong, and will be a big waste of bandwidth.
You can create a custom JSON encoder as per your requirement.
The Decoder can be called like this,
and the output will be:
How about subclassing
json.JSONEncoder
?Then use it like so:
From the JSON Standard Document, as linked in json.org:
So it's actually accurate to represent Decimals as numbers (rather than strings) in JSON. Bellow lies a possible solution to the problem.
Define a custom JSON encoder:
Then use it when serializing your data:
As noted from comments on the other answers, older versions of python might mess up the representation when converting to float, but that's not the case anymore.
To get that exact decimal back in Python:
This solution is hinted in Python 3.0 documentation on decimals:
This is what I have, extracted from our class
Which passes unittest:
My $.02!
I extend a bunch of the JSON encoder since I am serializing tons of data for my web server. Here's some nice code. Note that it's easily extendable to pretty much any data format you feel like and will reproduce 3.9 as
"thing": 3.9
Makes my life so much easier...
I tried switching from simplejson to builtin json for GAE 2.7, and had issues with the decimal. If default returned str(o) there were quotes (because _iterencode calls _iterencode on the results of default), and float(o) would remove trailing 0.
If default returns an object of a class that inherits from float (or anything that calls repr without additional formatting) and has a custom __repr__ method, it seems to work like I want it to.