“Decimal”类型的对象不可 JSON 序列化

pap*_*api 13 python json

由于客户函数错误,Lambda 执行失败,状态为 200:“Decimal”类型的对象不可 JSON 序列化

我在以下链接中浏览了所有现有的解决方案,但没有任何对我有用。我做错了什么?: Python JSON 序列化 Decimal 对象

import json
import boto3
import decimal


client = boto3.resource('dynamodb')
table = client.Table('table')

def lambda_handler(event, context):
    method = event["httpMethod"]
    print(event)
    if method=="POST":
        return POST(event)
    elif method=="DELETE":
        return DELETE(event)
    elif method=="GET":
        return GET(event)

#the respons format
def send_respons(responseBody, statusCode):
    response = {
        "statusCode": statusCode,
        "headers": {
            "my_header": "my_value"
        },
        "body": json.dumps(responseBody),
        "isBase64Encoded": 'false'
    }
    return response
    

def GET(event):
    tab = table.scan()['Items']
    ids = []
            for item in tab:
                    ids.append({"id":item["id"], "decimalOBJ":decimal.Decimal(item["decimalOBJ"]}))
            return send_respons(ids, 201)
Run Code Online (Sandbox Code Playgroud)

小智 29

这是扩展json 文档中也指定的JSONEncoder处理类型的示例Decimal

from decimal import Decimal

class DecimalEncoder(json.JSONEncoder):
  def default(self, obj):
    if isinstance(obj, Decimal):
      return str(obj)
    return json.JSONEncoder.default(self, obj)
Run Code Online (Sandbox Code Playgroud)

使用调用它

json.dumps(some_object, cls=DecimalEncoder)
Run Code Online (Sandbox Code Playgroud)

通过转换,str将保持良好的精度,而无需依赖外部封装。


hd1*_*hd1 15

看来你有两个选择:

  1. 也许最简单,您可以序列化 Decimal 对象的 int/float 值:

""" assume d is your decimal object """

serializable_d = int(d) # or float(d)

d_json = json.dumps(d)

  1. 您可以将simplejson添加到您的requirements.txt,它现在支持序列化小数。它是包含的 json 模块的直接替代品。
import simplejson as json # instead of import json
Run Code Online (Sandbox Code Playgroud)

其余代码的工作方式相同。如果您需要进一步的帮助,请发表评论。

  • 小数对象是专门为了准确性而存在的;铸造为浮动有可能增加不确定性。在将 Decimal 转换为另一种类型之前,我会使用字符串值。 (4认同)

Sma*_* Ma 5

创建一个函数来处理TypeError并使用default参数json.dumps来设置它。这就避免了TypeError: Object of type Decimal is not JSON serializable

\n

https://docs.python.org/3/library/json.html

\n
\n

如果指定,默认值应该是一个为\n可以\xe2\x80\x99t否则被序列化的对象调用的函数。它应该返回对象的 JSON\n可编码版本或引发 TypeError。如果未指定,则会引发 TypeError。

\n
\n

json_utils.py:

\n
import decimal\nimport json\n\n\ndef dumps(item: dict) -> str:\n    return json.dumps(item, default=default_type_error_handler)\n\n\ndef default_type_error_handler(obj):\n    if isinstance(obj, decimal.Decimal):\n        return int(obj)\n    raise TypeError\n
Run Code Online (Sandbox Code Playgroud)\n

test_json_utils.py:

\n
import json\nfrom decimal import Decimal\nfrom commons import json_utils\n\n\ndef test_different_data_types():\n    # Prepare data\n    item = {\n        "a-string": "lorem",\n        "a-boolean": True,\n        "a-number": 4711,\n        "a-decimal-object": Decimal(4711)  # Used by dynamoDb boto3 client\n    }\n\n    # Execute\n    item_as_json = json_utils.dumps(item)\n\n    # Assert\n    item_back_to_dict = json.loads(item_as_json)\n    assert item_back_to_dict == item\n
Run Code Online (Sandbox Code Playgroud)\n