特定异常输出

时间:2014-11-19 21:22:39

标签: python json

我试图在我的活动KeyError中找出我的代码的哪一部分包含list。事件是包含JSON元素的列表。我想将timestampevent_sequence_numberdevice_id放在各自的变量中。但是,每个JSON对象都不同,有些不包含timestampevent_sequence_numberdevice_id个键。如何更改我的代码,以便我能够输出哪些特定的密钥丢失?

前:

缺少时间戳

"timestamp key is missing"

缺少时间戳和device_id时

"timestamp key is missing"
"device_id key is missing"

代码:

for event in events:
    try:
        timestamp = event["event"]["timestamp"]
        event_sequence_num = event["event"]["properties"]["event_sequence_number"]
        device_id = event["application"]["mobile"]["device_id"]
        event_identifier = str(device_id) + "_" + str(timestamp) + "_" + str(event_sequence_num)
        event_dict[event_identifier] = 1
    except KeyError:
        print "JSON Key does not exist"  

2 个答案:

答案 0 :(得分:1)

您可以打印例外,因为其中包含KeyError被引发的密钥:

except KeyError as exc:
    print "JSON Key does not exist: " + str(exc)

您还可以通过查看exc.args[0]

来访问密钥
except KeyError as exc:
    print "JSON Key does not exist: " + str(exc.args[0])

答案 1 :(得分:1)

Simeon Visser's answer是正确的。报告导致KeyError的密钥可能是在简单,直接的Python中可以做到的最好的。如果您只访问一次JSON结构,那就是最佳选择。

但是,对于需要重复访问多级事件数据的情况,我提供了更长的选择。如果您经常访问它,您的程序可以提供更多的设置和基础架构。考虑:

def getpath(obj, path, post=str):
    """
    Use path as sequence of keys/indices into obj. Return the value
    there, filtered through the post (postprocessing function).
    If there is no such value, raise KeyError displaying the
    partial path to the point where there is no index/key.
    """
    c = obj
    try:
        for i, p in enumerate(path):
            c = c[p]
        return post(c) if post else c
    except (KeyError, IndexError) as e:
        msg = "JSON keys {0!r} don't exist".format(path[:i+1])
        raise KeyError(msg)

        # raise type(e)(msg) # Alternative if you want more exception variety

EID_COMPONENTS = [('application', 'mobile', 'device_id'),
                  ('event', 'timestamp'),
                  ('event', 'properties', 'event_sequence_number')]

for event in events:
    event_identifier = '_'.join(getpath(event, p) for p in EID_COMPONENTS)
    event_dict[event_identifier] = 1

这里有更多的准备工作,具有单独的getpath函数和全局定义的规范,用于获取要获取的JSON数据的路径。从好的方面来说,event_identifier的集合要短得多(如果它被包裹在一个函数中,它的大小约为源代码行或字节代码的1/3)。

如果尝试访问失败,它将返回一个更完整的错误消息,将结构路径提供到该点,而不仅仅是缺少的最终密钥。在具有不同子结构(例如多个timestamp)中的重复键的复杂JSON中,知道哪些尝试访问失败可以为您节省大量调试工作。您可能还注意到代码已准备好使用整数索引并正常处理IndexError;在JSON中,数组值很常见。

这是抽象的行动:更多框架和更多设置,但如果您需要进行大量深层结构访问,节省代码大小和更好的错误报告将有利于您的程序的多个部分,使其成为一个很好的投资。