【问题标题】:python simpleJSONDecoder and complex JSON issuepython simpleJSONDecoder和复杂的JSON问题
【发布时间】:2010-06-01 01:07:57
【问题描述】:

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

我查看了子对象,发现是“cpuid”对象导致了问题。当我删除它并运行测试时,它工作正常。

def _make_report_entry(record):
    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"I'm awesome.", 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 异常。

[抱歉之前不必要的长帖子,我希望这会缩小一点]

【问题讨论】:

  • 您能粘贴确切的错误吗?
  • 什么是self.json_encode?你写了什么??
  • 信息量很大,但还不够,因为看起来堆栈跟踪不完整——其中的轨迹暗示正在进行解码情况,不是一个 encoding 一个(正如你原来的 Q 建议的那样)。也许你误用了一些你自己的模型?不能说,因为我们看不到模型的定义。

标签: python json simplejson


【解决方案1】:

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

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

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

【讨论】:

  • 我刚刚更新了我的问题。格式化太可怕了。我看看能不能解决这个问题。
【解决方案2】:

回溯中的最后 2 行:

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

您现在有两个版本的def _make_report_entry(record):

请注意,回溯的前几行是关于 decode,而不是 encode。

第一个/原始版本与问题有什么关系?

您现在说“因为我的解码函数需要其他对象(例如,'type'、'instance_id' 等),我得到一个 KeyError 异常。”

因此,也许您的解码函数正在被递归调用,并且调用者希望能够处理任何结构,而不仅仅是具有“类型”等的结构。

【讨论】:

  • 您的第 3 点和第 4 点有点任性:内置的 dict() 具有您希望提供的任何关键字参数。 dict(record='string') 使用键 record 创建一个字典。
  • @Duncan:是的,我很傻,当它出现并忘记它时,我对 key=value 噱头并没有留下深刻印象
猜你喜欢
  • 2015-06-02
  • 1970-01-01
  • 2011-11-07
  • 2020-06-21
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多