【问题标题】:Pickle dumps giving garbage value给垃圾价值的泡菜垃圾场
【发布时间】:2013-09-07 15:46:54
【问题描述】:

您好,我正在使用 JSON 编码器,其中 pickle.dumps() 给了我奇怪的输出。输出如下:

"cdecimal Decimal p0 (S'2097369' p1 tp2 Rp3 .",

虽然,应该是:2097369

代码sn-p是:

class PythonObjectEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (list, dict, unicode, int, float, str, bool, type(None))):
            return JSONEncoder.default(self, obj)
        return pickle.dumps(obj)

    def as_python_object(dct):
        if '_python_object' in dct:
            return pickle.loads('')
        return dct

谁能告诉我出了什么问题,我怎样才能找回想要的值?

【问题讨论】:

  • 你传递给pickle的是什么样的对象?
  • 我正在传递一个十进制值。我有一个嵌套的字典,我正在尝试将其序列化为 JSON。为此,我正在使用此功能。早些时候它给出了错误,因为“TypeError: Decimal('2097369') is not JSON serializable”。但是在使用泡菜之后,我得到了一个垃圾值。帮帮我!
  • 这不是垃圾值,它是代表Decimal('2097369')对象的序列化字符串。 pickle.loads 可以将该字符串转换回Decimal 对象。
  • 我认为您将 pickle 序列化与 JSON 混淆了。 pickle 与 JSON 没有任何关系。

标签: python json pickle jsonpickle


【解决方案1】:

我认为这就是您要寻找的。 JSON 不支持的类型使用pickle 序列化为字符串,并以表明它是 Python 对象的格式存储。 object_hook 用于识别该格式,并在 json.loads 期间将腌制对象转换回 Python 对象:

from decimal import Decimal
import json
import pickle

class PythonObjectEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (dict,list,tuple,str,unicode,int,long,float,bool,type(None))):
            return json.JSONEncoder.default(self,obj)
        return {'_python_object_':pickle.dumps(obj)}

def as_python_object(dct):
    if u'_python_object_' in dct:
        return pickle.loads(dct[u'_python_object_'])
    return dct

obj = {'a':1,'b':'string','c':1.2,'d':Decimal('123.456')}
print obj # original object
j = json.dumps(obj,cls=PythonObjectEncoder,indent=2)
print j  # encoded object
obj = json.loads(j,object_hook=as_python_object)
print obj # decoded object

输出:

{'a': 1, 'c': 1.2, 'b': 'string', 'd': Decimal('123.456')}
{
  "a": 1, 
  "c": 1.2, 
  "b": "string", 
  "d": {
    "_python_object_": "cdecimal\nDecimal\np0\n(S'123.456'\np1\ntp2\nRp3\n."
  }
}
{u'a': 1, u'c': 1.2, u'b': u'string', u'd': Decimal('123.456')}

【讨论】: