2016-07-20 10 views
1

pack/unpackタプルにはいくつかの問題があります。私が知っているように、msgpackはリストとタプルを区別せず、リストやタプルを強制的にExtTypeにするフックはありません。それは不満足な問題を引き起こす。タプルとリストを使用してパック/アンパックする方法msgpack(任意のオブジェクトの汎用ソリューション)?

Periodのためだけでなく、すべてのタイプのオブジェクトに対して包括的なソリューションを実行したいとします。期間は固定する必要があると仮定するのは簡単ですが、実行したくありません。あなたはどのように任意のアイデアを持っていますか

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 

:私は考えてそれは容易に解決できない開梱中に問題が発生し

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 

:何も特別な -

__hash__で簡単な例クラスを参照してください。可能であれば、タプルをタプルに再構築し、msgpackを使用してリストにリストアップしますか?

答えて

0

dictのフックを書かなければならないのは、元のオブジェクトのPeriod((2016,7))などのキーがハッシュ可能(タプル)であり、リストに変換されてハッシュできないからです。 カスタムフックの場合、dictを の{Period((2016, 7)): 112, Period((2016, 8)): 231}[(Period((2016, 7)), 112), (Period((2016, 8)), 231)]に最初に変換する必要があるキーと値のペアのタプルとして保存できます。

とアンパック中にそれらをdictに変換します。そうすれば、リストの邪魔にならない性質が生まれることはありません。

関連する問題