You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在Boto3 DynamoDB序列化代码中使用三元运算符?

关于DynamoDB序列化代码中三元运算符的疑问

我看到一段将常规JSON对象序列化为DynamoDB JSON格式的代码,疑问在于:代码中的serialize函数使用了三元运算符vars(item) if hasattr(item, '__dict__') else item,但我在Lambda环境测试发现,直接将Python对象传入serialize方法即可正常运行,为何还要使用该三元运算符?是否是开发者不确定__dict__属性是否存在?

代码示例

from boto3.dynamodb.types import TypeSerializer, TypeDeserializer
import json

serializer = TypeSerializer()
deserializer = TypeDeserializer()

# for building a DynamoDB JSON from a Python object
def serialize(item):
    serialized_item = serializer.serialize(vars(item) if hasattr(item, '__dict__') else item)

    return item if 'M' not in serialized_item else serialized_item['M']

# for building a plain JSON from a DynamoDB JSON
def deserialize(dynamodb_json_string):
    return deserializer.deserialize({'M': dynamodb_json_string})

class MyItem:
    def __init__(self, some_string_value=None, some_numeric_value=None):
        self.my_key = some_string_value
        self.my_other_key = some_numeric_value

    def __str__(self):
        return json.dumps(self, default=lambda x: x.__dict__)

if __name__ == '__main__':
    my_classy_item = MyItem("my_string_value", 5)
    my_string_item = json.loads('{"my_key": "my_string_value", "my_other_key" : 5}')

    print(serialize(my_classy_item))
    print(serialize(my_string_item))

解答

这个三元运算符的存在主要是为了兼容自定义类实例和原生Python数据类型两种输入场景,同时避免潜在报错,具体原因如下:

  • 自定义类实例无法直接被序列化:boto3的TypeSerializer只支持序列化Python原生数据类型(如dict、str、int、list)和DynamoDB专属类型,没法直接处理自定义类的实例。比如直接把MyItem对象传给serializer.serialize(),会抛出TypeError。而vars(item)(等价于item.__dict__)能把自定义实例的属性转换成TypeSerializer能处理的dict格式。
  • 兼容多种输入类型:这段代码的serialize函数需要同时处理两种输入——自定义类实例(需要转成dict)和原生数据类型(比如代码里的my_string_item这种dict,或者直接传入的字符串、数字等)。三元运算符可以自动判断输入类型,对自定义实例转dict,对原生类型直接传入,保证函数的通用性。
  • 避免__dict__不存在的报错:不是所有Python类都有__dict__属性——比如用__slots__定义的类,会禁止自动生成__dict__来节省内存。hasattr(item, '__dict__')就是为了判断这种情况,避免直接调用vars(item)时抛出AttributeError。

你测试时直接传Python对象能运行,大概率是因为测试的自定义类刚好带有__dict__属性,或者误将已经转成dict的对象当成了原始实例。如果换成用__slots__定义的类,直接传实例给serializer.serialize()就会报错,这时候三元运算符的作用就体现出来了。

内容的提问来源于stack exchange,提问作者adethefirst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 20:52:37