我试图在我的活动KeyError
中找出我的代码的哪一部分包含list
。事件是包含JSON元素的列表。我想将timestamp
,event_sequence_number
和device_id
放在各自的变量中。但是,每个JSON对象都不同,有些不包含timestamp
,event_sequence_number
或device_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"
答案 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中,数组值很常见。
这是抽象的行动:更多框架和更多设置,但如果您需要进行大量深层结构访问,节省代码大小和更好的错误报告将有利于您的程序的多个部分,使其成为一个很好的投资。