To convert Decimal
during json.dump()
using default
parameter:
import json
import sys
from decimal import Decimal
def default(obj):
if isinstance(obj, Decimal):
return str(obj)
else:
raise TypeError(obj)
# convert during dump
json.dump(data, sys.stdout, indent=2, default=default)
To modify data
inplace:
import json
import sys
from collections import MutableMapping, MutableSequence
from decimal import Decimal
def convert_decimal(json_data):
stack = [json_data]
while stack:
json_data = stack.pop()
if isinstance(json_data, MutableMapping): # json object
it = json_data.items()
elif isinstance(json_data, MutableSequence): # json array
it = enumerate(json_data)
else: # scalar data
continue
for k, v in it:
if isinstance(v, Decimal):
json_data[k] = str(v)
else:
stack.append(v)
# convert inplace
convert_decimal(data)
json.dump(data, sys.stdout, indent=2)
Both scripts produce the same output:
[
{
"Payments": {
"OtherFees": "0",
"APR": "2.54",
"Rate": "0.0254",
"IsCapped": true,
"Name": "TestData",
"Program": {
"Description": null,
"ProgramName": "AST"
},
"AppliedIds": [],
"CapCostTotal": "27900",
"Tax": "0",
"Payment": "495.64"
}
}
]
You could simplify convert_decimal()
if you use a generic get_items()
function:
def convert_decimal(json_data):
stack = [json_data]
while stack:
json_data = stack.pop()
for k, v in get_items(json_data):
if isinstance(v, Decimal):
json_data[k] = str(v)
else:
stack.append(v)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…