簡體   English   中英

Python 3.x 無法將 Decimal() 序列化為 JSON

[英]Python 3.x cannot serialize Decimal() to JSON

我之前問過這個問題,它被標記為this 的重復,但接受的答案不起作用,甚至 pylint 顯示代碼中有錯誤。

我想做的事:

from decimal import Decimal
import json

thang = {
    'Items': [{'contact_id': Decimal('2'), 'street_name': 'Asdasd'}, {'contact_id': Decimal('1'), 'name': 'Lukas', 'customer_id': Decimal('1')}],
     'Count': 2}

print(json.dumps(thang))

這會拋出: TypeError: Object of type 'Decimal' is not JSON serializable

所以我嘗試了鏈接的答案

from decimal import Decimal
import json

thang = {
    'Items': [{'contact_id': Decimal('2'), 'street_name': 'Asdasd'}, {'contact_id': Decimal('1'), 'name': 'Lukas', 'customer_id': Decimal('1')}],
     'Count': 2}


class DecimalEncoder(json.JSONEncoder):
    def _iterencode(self, o, markers=None):
        if isinstance(o, Decimal):
            # wanted a simple yield str(o) in the next line,
            # but that would mean a yield on the line with super(...),
            # which wouldn't work (see my comment below), so...
            return (str(o) for o in [o])
        return super(DecimalEncoder, self)._iterencode(o, markers)


print(json.dumps(thang, cls=DecimalEncoder))

這里 linter 顯示 line return super(DecimalEncoder, self)._iterencode(o, markers)有錯誤,因為Super of 'DecimalEncoder' has no '_iterencode' member並且在運行時拋出TypeError: Object of type 'Decimal' is not JSON serializable

我如何使這項工作?

結果證明該答案已過時,工作解決方案還有另一個答案

class DecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, decimal.Decimal):
            return str(o)
        return super(DecimalEncoder, self).default(o)

請注意,這會將十進制數轉換為其字符串表示形式(例如; "1.2300" )到 a。 不會丟失有效數字和 b. 防止舍入錯誤。

我想將 Decimal序列化為JSON,並將其反序列化回其他地方字典中的實際 Decimal 類對象。

這是我的示例程序(Python 3.6):

import json
from decimal import Decimal
import decimal

class DecimalEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, decimal.Decimal):
            return {'__Decimal__': str(obj)}
        # Let the base class default method raise the TypeError
        return json.JSONEncoder.default(self, obj)

def as_Decimal(dct):
    if '__Decimal__' in dct:
        return decimal.Decimal(dct['__Decimal__'])
    return dct


sample_dict = {
        "sample1": Decimal("100"), 
        "sample2": [ Decimal("2.0"), Decimal("2.1") ],
        "sample3": Decimal("3.1415"),
        "other": "hello!"
    }
print("1. sample_dict is:\n{0}\n".format(sample_dict))

sample_dict_encoded_as_json_string = json.dumps(sample_dict, cls=DecimalEncoder)
print("2. sample_dict_encoded_as_json_string is:\n{0}\n".format(sample_dict_encoded_as_json_string))

sample_dict_recreated = json.loads(sample_dict_encoded_as_json_string, object_hook=as_Decimal)
print("3. sample_dict_recreated is:\n{0}\n".format(sample_dict_recreated))

這是輸出:

1. sample_dict is:
{'sample1': Decimal('100'), 'sample2': [Decimal('2.0'), Decimal('2.1')], 'sample3': Decimal('3.1415'), 'other': 'hello!'}

2. sample_dict_encoded_as_json_string is:
{"sample1": {"__Decimal__": "100"}, "sample2": [{"__Decimal__": "2.0"}, {"__Decimal__": "2.1"}], "sample3": {"__Decimal__": "3.1415"}, "other": "hello!"}

3. sample_dict_recreated is:
{'sample1': Decimal('100'), 'sample2': [Decimal('2.0'), Decimal('2.1')], 'sample3': Decimal('3.1415'), 'other': 'hello!'}

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM