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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:10:38