2016-07-20 12 views
1

Hier ist ein Problem mit Pack/Unpack Tupel. Wie ich weiß, unterscheidet msgpack nicht zwischen list und tuple und es gibt keinen Hook, um Liste oder Tupel zu zwingen, ExtType zu sein. Es erzeugt frustrierende Probleme.Wie Tupel packen/entpacken und mit msgpack auflisten (generische Lösung für jedes Objekt)?

Angenommen, ich möchte generische Lösung für alle Arten von Objekten nicht nur für die Periode - es ist einfach anzunehmen, dass der Schlüssel für die Periode festgelegt werden soll, aber es ist nicht wollen, ich möchte tun.

Siehe einfaches Beispiel Klasse mit __hash__ - nichts Besonderes:

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 

Es Problem beim Auspacken erzeugt, die nicht leicht gelöst werden kann, denke ich:

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 

Haben Sie eine Ahnung, wie man Tupel zu Tupeln rekonstruieren und mit msgpack zu Listen auflisten, wenn es überhaupt möglich ist?

Antwort

0

Für Ihre Objekte müssten Sie auch Hooks für dict schreiben, weil Ihre Schlüssel Period((2016,7)) usw. im Originalobjekt hashbar sind (ein Tupel sein), konvertiert werden in eine Liste, die nicht hashbar ist. Für Ihre benutzerdefinierten Hooks können Sie das Diktat als Tupel von Schlüssel/Wert-Paaren speichern, , d. H. {Period((2016, 7)): 112, Period((2016, 8)): 231} sollte zuerst in [(Period((2016, 7)), 112), (Period((2016, 8)), 231)] konvertiert werden.

und wandeln Sie sie beim Entpacken in dict um. Auf diese Weise kommt die Unabnehmbarkeit von Listen nicht zur Geltung.