python simpleJSONDecoder和复杂的JSON问题

时间:2010-06-01 01:07:58

标签: python json simplejson

在我正在运行的单元测试用例中,我在下面的json文本中的第4个json对象上得到了一个KeyError异常,因为负责解码的代码片段正在查找不存在的对象,但应该是。

我浏览了子对象,发现导致问题的是“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}
                    ])))

在正在测试的代码片段中,我使用django.utils中的simplejson.JSONDecoder来解码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'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 个答案:

答案 0 :(得分:1)

复制并粘贴您传递给self.json_encode的内容,并将其用作json.dumps的参数(在Python 2.6中的import json之后),可以正常工作。所以看起来这个bug可能在你没有向我们展示的json_encode方法中:它除了只是调用json.dumps之外还做了什么呢? (或simplejson.dumps如果您使用的是Python< 2.6,当然。)

修改:使用json_encode = json.JSONEncoder().encode(正如OP刚刚发布的那样,除了使用旧的simplejson,因为我提到的可能性)也可以。不完整的堆栈跟踪也作为Q的大型编辑的一部分发布,表明错误来自解码部分,可能是通过滥用某些模型(不能说,因为我们没有看到模型) - 正如OP所提到的,他现在发布了更多信息,但仍然不足以调试问题。

这有力地表明,OP一次尝试简化问题是值得的,直到最后一次增量简化使错误消失 - 这通常会强烈暗示错误可能是什么,但即使它没有,发布最简单的方法来重现bug以及如果进一步删除代码的微小epsilon将消失的信息可能有助于像我们这样的“第三方观察者”协助调试。 SO并不是一个专为集体调试而设计的平台(更适合于问题和答案, 设计的用途),但我不认为它违反了SO的规则,试图将它用于这个不同的目的

答案 1 :(得分:0)

追溯中的最后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异常。”

所以也许你的解码函数是递归调用的,并且调用者希望能够处理任何结构,而不仅仅是'type'等。