python simpleJSONDecoder и сложная проблема JSON - PullRequest
0 голосов
/ 01 июня 2010

В модульном тесте, который я запускаю, я получаю исключение KeyError для 4-го объекта json в тексте json ниже, потому что фрагмент кода, отвечающий за декодирование, ищет объект, которого нет, но он должен быть ,

Я просмотрел подобъекты и обнаружил, что это был объект "cpuid", который вызывает проблему. Когда я удаляю его и запускаю тест, он работает нормально.

def _make_report_entry (запись):

    response = self.app.post(
        '/machinestats',
        params=dict(record=self.json_encode([
                    {"type": "crash", "instance_id": "xxx",
                     "version": "0.2.0", "build_id": "unknown",
                     "crash_text": "Gah!"},
                    {"type": "machine_info", "machine_info": "I'm awesome.",
                     "version": "0.2.0", "build_id": "unknown",
                     "instance_id": "yyy"},
                    {"machine_info": "Soup", "crash_text": "boom!",
                     "version": "0.2.0", "build_id": "unknown",
                     "instance_id": "zzz", "type": "crash"},
                    {"build_id" : "unknown", "cpu_brand" : "intel",
                     "cpu_count" : 4,
                     "cpuid": {
                               "00000000":
                                    {"eax" :123,"ebx" :456,
                                     "ecx" :789,"edx" :321},
                               "00000001":
                                    {"eax" :123,"ebx" :456,
                                     "ecx" :789,"edx" :321}},
                     "driver_installed" : True,
                     "instance_id" : "yyy",
                     "version" : "0.2.0",
                     "machine_info" : "I'm awesome.",
                     "os_version" : "linux",
                     "physical_memory_mib" : 1024,
                     "product_loaded" : True,
                     "type" : "machine_info",
                     "virtualization_advertised" : True}
                    ])))

В тестируемом фрагменте кода я использую simplejson.JSONDecoder из django.utils для декодирования JSON. Когда я регистрирую декодированный вывод для вышеуказанного JSON, который передается в мою функцию декодирования, я получаю это:

root: INFO: {u'instance_id ': u'xxx', u'type ': u'crash', u'crash_text ': u'Gah!', U'version ': u'0.2.0' , u'build_id ': u'unknown'}

root: INFO: {u'build_id ': u'unknown', u'instance_id ': u'yyy', u'version ': u'0.2.0', u'machine_info ': u "Я удивительно. ", u'type ': u'machine_info'}

root: INFO: {u'build_id ': u'unknown', u'machine_info ': u'Soup', u'version ': u'0.2.0', u'instance_id ': u'zzz', u'crash_text ': u'boom!', u'type ': u'crash'}

root: INFO: {u'eax ': 123, u'edx': 321, u'ebx ': 456, u'ecx': 789}

В последнем объекте JSON только объект в объекте JSON cpuid передается в мою функцию декодирования. Поскольку моя функция декодирования ожидает другие объекты (например, 'type', 'instance_id' и т. Д.), Я получаю исключение KeyError.

[Извините за ранее неоправданно длинный пост, я надеюсь, что это сузит его еще немного]

Ответы [ 2 ]

1 голос
/ 01 июня 2010

Копирование и вставка того, что вы передаете self.json_encode, и использование его в качестве аргумента json.dumps (после import json в Python 2.6), работает просто отлично. Похоже, ошибка может быть в методе json_encode, который вы нам не показываете: что еще он делает, кроме простого вызова json.dumps ...? (или simplejson.dumps, если вы используете Python <2.6, конечно). </p>

Редактировать : использование json_encode = json.JSONEncoder().encode (как только что опубликованный ОП, за исключением того, что используется более старый simplejson, как я уже упоминал в качестве возможности) также работает нормально. Неполная трассировка стека, также опубликованная как часть большого редактирования Q, предполагает, что ошибка возникает в части декодирования , возможно, из-за неправильного использования некоторой модели (не могу сказать, поскольку мы не видим модели ) - как упомянул ОП, он теперь опубликовал гораздо больше информации, и все же этого недостаточно для устранения проблемы.

Это настоятельно говорит о том, что для ОП целесообразно попытаться немного упростить проблему за раз, пока последнее постепенное упрощение не устранит ошибку - это обычно сильно намекает на то, какой может быть ошибка, но даже если это не так, публикация самого крошечного способа воспроизвести ошибку плюс информация о том, что ошибка исчезнет, ​​если в дальнейшем будет удален незначительный эпсилон кода, может помочь «сторонним наблюдателям», таким как все мы, помочь в отладке. SO на самом деле не является платформой, предназначенной для коллективной отладки (лучше работает для вопросов и ответов, для чего она была предназначена ), но я не думаю, что она нарушает правила SO, пытаясь использовать ее для этой другой цели.

0 голосов
/ 01 июня 2010

Последние 2 строки в трассировке:

File "...j_report/src/jreport/machinestats.py", line 77, in _make_report_entry
entry_type=record['type']

Теперь у вас есть ДВА версии def _make_report_entry(record):

Обратите внимание, что первые несколько строк трассировки бормочут о декодировании , а не кодировании.

Какое отношение имеет первая / оригинальная версия к проблеме?

Теперь вы говорите: «Поскольку моя функция декодирования ожидает другие объекты (например,« type »,« instance_id »и т. Д.), Я получаю исключение KeyError».

Так что, возможно, ваша функция декодирования вызывается рекурсивно и ожидается, что вызывающая сторона сможет обрабатывать ЛЮБУЮ структуру, а не только с типом и т. Д.

...