2016-03-08 38 views
2

我的數據結構是這樣的:使用msgpack的Python嵌套namedtuples

user = UserTuple(
    name=u'Anakin', surname=u'Skywalker', birthdate=datetime.date(1981, 7, 25), 
    profile=ProfileTuple(avatar=u'http://localhost/profile.jpg') 
) 

我要打包帶msgpack-Python模塊此數據。但msgpack將namedtuples轉換爲列表。可以用msgpack打包這樣的數據並保存namedtuples,就像pickle/cpickle一樣?

回答

4

你需要有最新版本msgpack-pythonv0.4.7不起作用。 (目前必須從主分支安裝)。

import msgpack 
from collections import namedtuple 

User = namedtuple('User', ['name', 'profile']) 
Profile = namedtuple('Profile', ['avatar']) 

def ext_pack(x): 
    if isinstance(x, User): 
     return msgpack.ExtType(1, msgpack.packb([x[0], x[1]], default=ext_pack, strict_types=True)) 
    elif isinstance(x, Profile): 
     return msgpack.ExtType(2, msgpack.packb(x[0], default=ext_pack, strict_types=True)) 
    return x 

def ext_unpack(code, data): 
    if code == 1: 
     name, profile = msgpack.unpackb(data, ext_hook=ext_unpack) 
     return User(name, profile) 
    elif code == 2: 
     avatar = msgpack.unpackb(data, ext_hook=ext_unpack) 
     return Profile(avatar) 
    return msgpack.ExtType(code, data) 

x = User("me", Profile(234)) 
s = msgpack.packb([x, [1, x]], default=ext_pack, strict_types=True) 
msgpack.unpackb(s, ext_hook=ext_unpack) 
>>> [User(name='me', profile=Profile(avatar=234)), 
[1, User(name='me', profile=Profile(avatar=234))]] 

在這裏,我們分別標記UserProfile如類型代碼1,2。或者,您可以將所有namedtuple視爲相同類型的代碼,並將實際類型存儲在數據字段中。