如何使用msgpack(任何对象的通用解决方案)打包/解包元组和列表?

时间:2016-07-20 19:50:02

标签: python python-2.7 serialization msgpack

这是打包/解包元组的一些问题。据我所知,msgpack不区分列表和元组,并且没有挂钩强制列表或元组是ExtType。它会产生令人沮丧的问题。

假设我想为所有类型的对象做一个通用的解决方案,而不仅仅是对于Period - 很容易假设应该为Period修复密钥,但我不希望这样做。

使用 __ hash __ 查看简单的示例类 - 没什么特别的:

import msgpack

class Period(object):
    def __init__(self, key):
        self.key = key

    def __hash__(self):
        return hash(self.key)

    def __eq__(self, other):
        self.key == self.key

def encode(o):
    if type(o) is Period:
        return msgpack.ExtType(0, msgpack.dumps(o.__dict__))

def decode_ext(code, data):
    if code == 0:
        o = Period.__new__(Period)
        o.__dict__ = msgpack.loads(data)
        return o

o = {Period((2016, 7)): 112, Period((2016, 8)): 231}

print o
s = msgpack.dumps(o, default=encode)
print s
o2 = msgpack.loads(s, ext_hook=decode_ext)
print o2

它在拆包过程中会产生问题,这个问题无法轻易解决,我想:

C:\root\Python27-64\python.exe "C:/Users/Cezary Wagner/PycharmProjects/msgpack_learn/src/02_tuple_wrong_pack.py"
Traceback (most recent call last):
{<__main__.Period object at 0x0000000002941668>: 231, <__main__.Period object at 0x0000000002941AC8>: 112}
  File "C:/Users/Cezary Wagner/PycharmProjects/msgpack_learn/src/02_tuple_wrong_pack.py", line 28, in <module>
��
    o2 = msgpack.loads(s, ext_hook=decode_ext)
 ��key������
  File "msgpack/_unpacker.pyx", line 139, in msgpack._unpacker.unpackb (msgpack/_unpacker.cpp:139)
 ��key���p
  File "C:/Users/Cezary Wagner/PycharmProjects/msgpack_learn/src/02_tuple_wrong_pack.py", line 8, in __hash__
    return hash(self.key)
TypeError: unhashable type: 'list'

Process finished with exit code 1

你知道如何将元组重建为元组并使用msgpack列表到列表吗?

1 个答案:

答案 0 :(得分:0)

对于你的对象,你也必须为<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.alefba.app.cus.eLearning" android:installLocation="auto"> <uses-permission android:name="android.permission.INTERNET" /> <application ... </application> </manifest> 编写钩子,这是因为你的键dict等在原始对象中是可清除的(是一个元组),转换为list是不可动摇的。 对于自定义挂钩,您可以将dict存储为键值对的元组, 即Period((2016,7))应首先转换为{Period((2016, 7)): 112, Period((2016, 8)): 231}

并在解压缩时将它们转换为dict。这样,列表的不可能性就不会出现了。