2011-01-27 30 views
7

我有這樣如何使simplejson序列化的類

class A: 
    def __init__(self): 
     self.item1 = None 
    def __repr__(self): 
     return str(self.__dict__) 

當我做定義的類:

>>> import simplejson 
>>> myA = A() 
>>> simplejson.dumps(myA) 
TypeError: {'item1': None} is not JSON serializable 

我找不到原因。

我是否需要將任何特定的方法添加到simplejson來序列化我的類對象?

回答

10

您不能使用simplejson序列化任意對象。您需要通過defaultobject_hookdumpload。這裏有一個例子:

class SerializerRegistry(object): 
    def __init__(self): 
     self._classes = {} 
    def add(self, cls): 
     self._classes[cls.__module__, cls.__name__] = cls 
     return cls 
    def object_hook(self, dct): 
     module, cls_name = dct.pop('__type__', (None, None)) 
     if cls_name is not None: 
      return self._classes[module, cls_name].from_dict(dct) 
     else: 
      return dct 
    def default(self, obj): 
     dct = obj.to_dict() 
     dct['__type__'] = [type(obj).__module__, 
          type(obj).__name__] 
     return dct 

registry = SerializerRegistry() 

@registry.add 
class A(object): 
    def __init__(self, item1): 
     self.item1 = item1 
    def __repr__(self): 
     return str(self.__dict__) 
    def to_dict(self): 
     return dict(item1=self.item1) 
    @classmethod 
    def from_dict(cls, dct): 
     return cls(**dct) 

s = json.dumps(A(1), default=registry.default) 
a = json.loads(s, object_hook=registry.object_hook) 

這導致了這個:

>>> s 
'{"item1": 1, "__type__": ["__main__", "A"]}' 
>>> a 
{'item1': 1} 

但是你真正需要的是一個功能default,從您希望序列化對象創建的字典,並返回一個函數object_hook一個對象(正確的類型),如果一個字典不夠用,它會被賦予一個字典。最好的方法是在可序列化的類上創建一個方法,從對象中創建一個字典並將其構造回來,並且還有一個映射來識別字典屬於哪個類。

您還可以將一個標識符添加到要用作_classes索引的類中。這樣,如果您需要移動課程,則不會有任何問題。

+0

這個答案是正確的,但我不檢查它,因爲這個例子不是很簡單。謝謝! – dnuske 2012-08-14 23:24:54

3

根據json module docs(simplejson在Python 2.6中作爲json採用),您需要擴展json.JSONEncoder類,覆蓋其默認方法以將您的對象轉換爲可以序列化的類型。似乎沒有它在你的對象上尋找的方法。