Đối với những người không muốn sử dụng thư viện của bên thứ ba ... Một vấn đề với câu trả lời của Elias Zamaria là nó chuyển thành nổi, có thể gặp vấn đề. Ví dụ:
>>> json.dumps({'x': Decimal('0.0000001')}, cls=DecimalEncoder)
'{"x": 1e-07}'
>>> json.dumps({'x': Decimal('100000000000.01734')}, cls=DecimalEncoder)
'{"x": 100000000000.01733}'
Các JSONEncoder.encode()
phương pháp cho phép bạn trả về nội dung json đen, không giống như JSONEncoder.default()
, đã bạn quay trở lại một loại tương thích json (như phao) mà sau đó được mã hóa theo cách thông thường. Vấn đề encode()
là nó (bình thường) chỉ hoạt động ở cấp cao nhất. Nhưng nó vẫn có thể sử dụng được, với một chút công việc phụ (python 3.x):
import json
from collections.abc import Mapping, Iterable
from decimal import Decimal
class DecimalEncoder(json.JSONEncoder):
def encode(self, obj):
if isinstance(obj, Mapping):
return '{' + ', '.join(f'{self.encode(k)}: {self.encode(v)}' for (k, v) in obj.items()) + '}'
if isinstance(obj, Iterable) and (not isinstance(obj, str)):
return '[' + ', '.join(map(self.encode, obj)) + ']'
if isinstance(obj, Decimal):
return f'{obj.normalize():f}' # using normalize() gets rid of trailing 0s, using ':f' prevents scientific notation
return super().encode(obj)
Cung cấp cho bạn:
>>> json.dumps({'x': Decimal('0.0000001')}, cls=DecimalEncoder)
'{"x": 0.0000001}'
>>> json.dumps({'x': Decimal('100000000000.01734')}, cls=DecimalEncoder)
'{"x": 100000000000.01734}'