使用json.loads时出现KeyError

13 投票
10 回答
101710 浏览
提问于 2025-04-15 21:53

JSON在处理以下语句时似乎出现了一些问题:

{"delete":{"status":{"id":12600579001,"user_id":55389449}}}

代码片段:

temp = json.loads(line)
text = temp['text']

当上面的代码片段遇到类似于上面这个JSON“字典”的行时,我得到了以下错误信息:

text = temp['text']
KeyError: 'text'

这是因为那一行没有“text”这个键,还是因为“delete”不在字典里呢?

10 个回答

8

是因为这一行里没有“text”这个键,还是因为“delete”不在字典里呢?

其实是因为没有“text”这个键。如果你用 print temp 打印一下,或者检查一下结果中的 Python 字典里有没有 'text' 这个键,你会发现根本没有叫 'text' 的键。实际上,temp 里只有一个键:'delete'。而 'delete' 这个键对应的字典里只有一个键 'status',它又包含了一个字典,这个字典里有两个键:'user_id''id'

换句话说,你的结构是这样的:

{
    "delete" : {
        "status" : {
            "id" : 12600579001,
            "user_id" : 55389449
        }
    }
}

正如你所看到的,哪里都没有“text”这个键。

而且,你可以自己检查一下:

>>> 'text' in temp
False
>>> 'delete' in temp
True
14

如果你想在字典中查找一个键,但这个键可能不存在,可以使用 dict.get(key[, default]) 方法。比如说,使用 temp.get('text') 代替 temp['text']。这样做的好处是,如果这个键不存在,程序不会报错,而是会返回一个空值 None

在Python中,有一种编程风格叫做EAFP(先请求原谅,再请求许可),这种方式比LBYL(先看再跳)更符合Python的风格。

14

看起来这个问题是因为里面没有'text'这个东西。也许你可以用下面的方式

'text' in temp

在尝试使用'text'之前,先检查一下它是否存在。

编辑:

我参考了评论中的例子,并在里面加了一个if/elif/else的结构。

#! /usr/bin/python
import sys
import json
f = open(sys.argv[1])
for line in f:
    j = json.loads(line)
    try:
        if 'text' in j:
            print 'TEXT: ', j['text']
        elif 'delete' in j:
            print 'DELETE: ', j['delete']
        else:
            print 'Everything: ', j
    except: 
        print "EXCEPTION: ", j

示例片段 #1:

{u'favorited': False, u'contributors': None, u'truncated': False, u'text': ---- 省略 ---- }

示例片段 #2:

{u'delete': {u'status': {u'user_id': 55389449, u'id': 12600579001L}}}

撰写回答