Üçüncü taraf bir kütüphane kullanmak istemeyenler için ... Elias Zamaria'nın cevabı ile ilgili bir sorun, şamandıraya dönüşmesi ve sorunlara yol açmasıdır. Örneğin:
>>> json.dumps({'x': Decimal('0.0000001')}, cls=DecimalEncoder)
'{"x": 1e-07}'
>>> json.dumps({'x': Decimal('100000000000.01734')}, cls=DecimalEncoder)
'{"x": 100000000000.01733}'
JSONEncoder.encode()
Yöntem aksine sen, edebi json içeriği döndüren sağlar JSONEncoder.default()
Eğer (şamandıra gibi) bir json uyumlu türü iade ettiği, daha sonra normal şekilde kodlanmış alır söyledi. Sorun, encode()
(normalde) yalnızca en üst düzeyde çalışmasıdır. Ama biraz daha fazla çalışma ile hala kullanılabilir (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)
Hangi size verir:
>>> json.dumps({'x': Decimal('0.0000001')}, cls=DecimalEncoder)
'{"x": 0.0000001}'
>>> json.dumps({'x': Decimal('100000000000.01734')}, cls=DecimalEncoder)
'{"x": 100000000000.01734}'