Python中如何将无__dict__的对象(含命名元组数组)转为带键JSON
问题:命名元组数组转带键JSON的通用方法
从第三方库获取的数据需要转换为包含键值对的JSON格式:
- Rect是命名元组,使用
_asdict()可成功转为带键的JSON - polygon是Point类型命名元组的数组,直接用
json.dumps()仅输出值,无对应键 - 尝试
vars(obj.rect)、.__dict__均失败,同时不清楚如何调试Rect和Polygon的类型
相关代码及输出
print('Rect : ', obj.rect) print('rect.json : ', json.dumps(obj.rect._asdict())) print('polygon : ', obj.polygon) # polygon是命名元组数组,此代码输出无键值 print('polygon.json : ', json.dumps(obj.polygon, skipkeys=False))
Rect : Rect(left=2264, top=1031, width=241, height=238) Rect.json : {'left': 2264, 'top': 1031, 'width': 241, 'height': 238} polygon : [Point(x=2260, y=131), Point(x=2261, y=367), Point(x=2500, y=360), Point(x=2502, y=119)] polygon.json : [[2260, 131], [2261, 367], [2500, 360], [2502, 119]]
解决方案
1. 调试类型的方法
要确认对象类型,直接用type()和属性检查:
# 查看Rect的类型 print(type(obj.rect)) # 检查是否为命名元组(命名元组是tuple子类且有_asdict方法) print(isinstance(obj.rect, tuple) and hasattr(obj.rect, '_asdict')) # 查看对象的所有属性/方法 print(dir(obj.rect))
2. 通用转换方法
命名元组的实例没有__dict__属性,必须用_asdict()转为字典。针对数组场景,有两种处理方式:
方式一:手动遍历转换
直接遍历polygon数组,逐个将Point转为字典:
print('polygon.json : ', json.dumps([p._asdict() for p in obj.polygon]))
方式二:自定义JSON编码器(推荐,通用)
编写自定义编码器,自动处理所有命名元组,无需每次手动遍历:
import json from typing import Any class NamedTupleEncoder(json.JSONEncoder): def default(self, o: Any) -> Any: # 判断是否为命名元组:是tuple子类且包含_asdict方法 if isinstance(o, tuple) and hasattr(o, '_asdict'): return o._asdict() # 其他类型交给父类处理 return super().default(o) # 使用编码器转换 print('polygon.json : ', json.dumps(obj.polygon, cls=NamedTupleEncoder))
执行后输出的polygon JSON会是带键值的格式:
[{"x":2260,"y":131},{"x":2261,"y":367},{"x":2500,"y":360},{"x":2502,"y":119}]
内容的提问来源于stack exchange,提问作者Tac Tacelosky
相关产品推荐
相关产品推荐

