如何将嵌套的namedtuple转换为字典?

问题描述:

我想将下面提到的嵌套namedtuple转换为字典。如何将嵌套的namedtuple转换为字典?

我使用Python 3.4.2psd-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()但由于数据没有用的,它被流的,我不想改变库本身什么。

+0

你想让字典看起来像什么?只是'{'版本':'1','xx':'0.0',...}'? –

+3

为什么你需要它是一个字典? “数据流式传输”是什么意思?有这么多的问题....... –

+2

你可以给一个更简单的例子,可以复制? – Alexander

通过递归解包._asdict().items(),您可以对unnamed namedtuples进行检查,检查值类型的实例并相应地解包嵌套的值。 instance checking of a namedtuple需要一些额外的努力来确保嵌套的namedtuples不被解包器看作纯粹的元组。

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)