Python dict / list mix不是JSON可序列化的

时间:2017-02-07 15:50:04

标签: python json dictionary

我有点难过。我正在尝试构建JSON字符串,并且它在我的程序中生成了一个回溯。真的很奇怪的是,如果我剪切并粘贴到控制台中,整个过程就会起作用。

首先,这是代码。

    def readgs2JSON(self, msg):
    d = {"Channel" : "Readings"}
    d["Sensor"] = msg.ReadingsChn.ReadingReport.attrib["Sensor"]
    d["ReadingID"] = msg.ReadingsChn.ReadingReport.attrib["ReadingID"]
    d["Detect"] = msg.ReadingsChn.ReadingReport.Data.attrib["Detect"]
    d["Level"] = msg.ReadingsChn.ReadingReport.Data.attrib["Level"]
    d["Units"] = msg.ReadingsChn.ReadingReport.Data.attrib["Units"]
    if "Id" in msg.ReadingsChn.ReadingReport.Data.attrib:
        d["Id"] = msg.ReadingsChn.ReadingReport.Data.attrib["Id"]
    d["SUD"] = [el.attrib for el in msg.ReadingsChn.ReadingReport.Data.iterchildren()]
    print d
    return d

变量msg是由lxml生成的客观化元素。打印时,代码生成的字典d看起来像这样。 (对不起,这很难读。它似乎不想很好地换行。)

{'Detect': 'NONE', 'Level': '0', 'SUD': [{'Type': 'int', 'Name':'Reading1', 'Value': '75856'}, {'Type': 'int', 'Name': 'Reading2', 'Value': '75857'}, {'Type': 'int', 'Name': 'Reading3', 'Value': '75858'}, {'Type': 'int', 'Name': 'Reading4', 'Value': '75859'}, {'Type': 'int', 'Name': 'ClockTicks', 'Value': '389'}, {'Type': 'array', 'Name': 'Spectrum', 'Value': 'None'}], 'Units': 'bars', 'ReadingID': 'R000009233', 'Sensor': 'SC001', 'Channel': 'Readings'}

所以,当我在程序中执行 json.dumps(d)时,我会得到回溯:

[Failure instance: Traceback: <type 'exceptions.TypeError'>: {'Type':   'int', 'Name': 'Reading1', 'Value': '75856'} is not JSON serializable
/usr/lib64/python2.7/site-packages/twisted/internet/base.py:1195:run
/usr/lib64/python2.7/site-packages/twisted/internet/base.py:1204:mainLoop
/usr/lib64/python2.7/site-packages/twisted/internet 
/base.py:825:runUntilCurrent
/usr/lib64/python2.7/site-packages/twisted/internet/task.py:239:__call__
--- <exception caught here> ---
/usr/lib64/python2.7/site-packages/twisted/internet
/defer.py:149:maybeDeferred
/home/max/workspace/canary/CCSIEventHandler.py:26:tick
/home/max/workspace/canary/CCSIEventHandler.py:99:event2Msg
/home/max/workspace/canary/sensorcache.py:715:writeToBuffer
/home/max/workspace/canary/CCSI2JSON.py:37:pushCCSIMessage
/usr/lib64/python2.7/json/__init__.py:244:dumps
/usr/lib64/python2.7/json/encoder.py:207:encode
/usr/lib64/python2.7/json/encoder.py:270:iterencode
/usr/lib64/python2.7/json/encoder.py:184:default
]

所以,真正奇怪的是,如果我从我的终端复制打印的字典,并将其传递到python控制台,那么整个过程就有效了!

>>> json.dumps(d)
'{"SUD": [{"Type": "int", "Name": "Reading1", "Value": "75856"}, {"Type": "int", "Name": "Reading2", "Value": "75857"}, {"Type": "int", "Name": "Reading3", "Value": "75858"}, {"Type": "int", "Name": "Reading4", "Value": "75859"}, {"Type": "int", "Name": "ClockTicks", "Value": "389"}, {"Type": "array", "Name": "Spectrum", "Value": "None"}], "Level": "0", "Detect": "NONE", "Units": "bars", "ReadingID": "R000009233", "Sensor": "SC001", "Channel": "Readings"}'

对于我的生活,我无法发现差异,但我不是JSON专家。还有其他人有这个问题吗?

原来我试图序列化lxml.etree._Attrib,我认为它是一本字典,因为它就像一个字典。这是构建字典的调整后的代码,并且工作正常。

    def readgs2JSON(self, msg):
    d = {"Channel" : "Readings"}
    d["Sensor"] = msg.ReadingsChn.ReadingReport.attrib["Sensor"]
    d["ReadingID"] = msg.ReadingsChn.ReadingReport.attrib["ReadingID"]
    d["Detect"] = msg.ReadingsChn.ReadingReport.Data.attrib["Detect"]
    d["Level"] = msg.ReadingsChn.ReadingReport.Data.attrib["Level"]
    d["Units"] = msg.ReadingsChn.ReadingReport.Data.attrib["Units"]
    if "Id" in msg.ReadingsChn.ReadingReport.Data.attrib:
        d["Id"] = msg.ReadingsChn.ReadingReport.Data.attrib["Id"]
    sud_list = []
    for el in msg.ReadingsChn.ReadingReport.Data.iterchildren():
        sud_dict = {}
        for item in el.attrib:
            sud_dict[item] = el.attrib[item]
        sud_list.append(sud_dict)
    if sud_list is not []:
        d["SUD"] = sud_list
    return d

1 个答案:

答案 0 :(得分:1)

msg.ReadingsChn.ReadingReport.Data的孩子属于某种特殊类型,并且不是JSON可序列化的。它正确打印到控制台的原因是因为该类型已被覆盖__str____repr__