如何将嵌套的命名元组转换为字典?

3
我正在尝试将下面提到的嵌套命名元组转换为字典。
我正在使用 Python 3.4.2 和 psd-tools-1.2。
TypeToolObjectSetting(version=1, xx=0.0, xy=-1.55729984301413, yx=1.6070307595731337, yy=0.0, tx=628.1016949152543, ty=516.5, text_version=50, descriptor1_version=16, text_data=Descriptor(name='', classID=b'TxLr', items=[(b'Txt ', String(value='34px')), (b'textGridding', Enum(type=b'textGridding', value=b'None')), (b'Ornt', Enum(type=b'Ornt', value=b'Hrzn')), (b'AntA', Enum(type=b'Annt', value=b'Anno')), (b'bounds', Descriptor(name='', classID=b'bounds', items=[(b'Left', UnitFloat(unit='POINTS', value=-10.0)), (b'Top ', UnitFloat(unit='POINTS', value=-6.908203125)), (b'Rght', UnitFloat(unit='POINTS', value=10.0)), (b'Btom', UnitFloat(unit='POINTS', value=2.42578125))])), (b'boundingBox', Descriptor(name='', classID=b'boundingBox', items=[(b'Left', UnitFloat(unit='POINTS', value=-9.34375)), (b'Top ', UnitFloat(unit='POINTS', value=-5.9375)), (b'Rght', UnitFloat(unit='POINTS', value=9.5)), (b'Btom', UnitFloat(unit='POINTS', value=1.609375))])), (b'TextIndex', Integer(value=0)), (b'EngineData', RawData(value=b'\n\n<<\n\t/EngineDict\n\t<<\n\t\t/Edito ... =8205'))]), warp_version=1, descriptor2_version=16, warp_data=Descriptor(name='', classID=b'warp', items=[(b'warpStyle', Enum(type=b'warpStyle', value=b'warpNone')), (b'warpValue', Double(value=0.0)), (b'warpPerspective', Double(value=0.0)), (b'warpPerspectiveOther', Double(value=0.0)), (b'warpRotate', Enum(type=b'Ornt', value=b'Hrzn'))]), left=0, top=0, right=0, bottom=0)

我尝试过使用_asdict(),但是由于数据正在被流式传输,并且我不想改变库本身的任何内容,因此它没有用。


你想让字典看起来像什么?只是 {'version': '1', 'xx': '0.0', ...} 吗? - Adam Smith
3
你为什么需要它是一个字典?你所说的“数据正在流式传输”是什么意思?有这么多问题...... - Adam Smith
2
你能给一个更简单的例子,可以复制吗? - Alexander
@AdamSmith 对于你的第一个问题,是的,我想要一个键值对字典;对于你的第二个问题……从字典中提取数据比从命名元组中提取数据更容易。 - Bhartendu
@Alexander 抱歉,我不能。 - Bhartendu
@AdamSmith 我正在从流中写入这些数据。 - Bhartendu
1个回答

19
您可以通过递归解包._asdict().items()来取消嵌套的命名元组,检查值类型的实例并相应地解包嵌套值。命名元组的实例检查需要额外的努力,以确保解包器不将嵌套的命名元组视为纯元组。
def isnamedtupleinstance(x):
    _type = type(x)
    bases = _type.__bases__
    if len(bases) != 1 or bases[0] != tuple:
        return False
    fields = getattr(_type, '_fields', None)
    if not isinstance(fields, tuple):
        return False
    return all(type(i)==str for i in fields)

def unpack(obj):
    if isinstance(obj, dict):
        return {key: unpack(value) for key, value in obj.items()}
    elif isinstance(obj, list):
        return [unpack(value) for value in obj]
    elif isnamedtupleinstance(obj):
        return {key: unpack(value) for key, value in obj._asdict().items()}
    elif isinstance(obj, tuple):
        return tuple(unpack(value) for value in obj)
    else:
        return obj

# data = TypeToolObjectSetting(version=1, xx=0.0, ..
unpacked_data = unpack(data)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接