2017-02-07 3 views
0

Я немного в тупике. Я пытаюсь построить строку JSON, и это создает трассировку в моей программе. Самое странное, что если я вырезаю и вставляю в консоль, все работает.Python dict/list mix не JSON serializable

Во-первых, вот код.

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 
] 

Итак, действительно странно, если я скопирую напечатанный dict из моего терминала и прохожу мимо него в консоль 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, который я считал словарем, поскольку он работает как dict. Вот скорректированный код, который создает словарь и работает правильно.

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

Дети из 'msg.ReadingsChn.ReadingReport.Data' имеют особый тип, и они не являются сериализуемыми JSON. Причина, по которой он правильно выводится на консоль, заключается в том, что этот тип переопределил '__str__' или' __repr__'. –

+0

Попробуйте 'print type (d [" SUD "] [0])' –

ответ

1

Дети msg.ReadingsChn.ReadingReport.Data имеют какого-то особого типа, и они не JSON сериализуемы. Причина, по которой он правильно выводится на консоль, заключается в том, что этот тип переопределил __str__ или __repr__.

+0

Конечно, d ["SUD"] [0] is ! –

Смежные вопросы