我正在使用以下代码从嵌套的json阅读数据:
data = json.loads(json_file.json)
for nodesUni in data["data"]["queryUnits"]['nodes']:
try:
tm = (nodesUni['sql']['busData'][0]['engine']['engType'])
except:
tm = ''
try:
to = (nodesUni['sql']['carData'][0]['engineData']['producer']['engName'])
except:
to = ''
json_output_for_one_GU_owner = {
"EngineType": tm,
"EngineName": to,
}
我遇到了一个无类型错误的问题(例如,这个错误根本不存在nodesUni['sql']['busData'][0]['engine']['engType']
,因为没有数据,所以我使用try/except。但我的代码更复杂,对每个值都使用try/except是疯狂的。有没有其他选项如何处理这个问题?
错误:“类型错误:“NoneType”对象不可订阅”
1条答案
按热度按时间bjp0bcyl1#
这并不简单,因为您的需求是无错误地遍历字典,并在最后得到一个空字符串值,所有这些都在一个非常简单的表达式中完成,就像级联
[]
操作符一样。第一种方法
我的方法是在加载json文件时添加一个钩子,这样它就可以无限地创建缺省字典
印刷品:
当访问一些不存在的键组合时(在任何级别),
superdefaultdict
递归地创建一个自身的defaultdict
(这是一个很好的模式,您可以在Is there a standard class for an infinitely nested defaultdict?中了解更多),允许任意数量的不存在的键级别。现在唯一的缺点是它返回一个
defaultdict(<function superdefaultdict at 0x000001ECEFA47160>, {})
,很难看。所以如果字典为空,则打印空字符串。这应该满足您的目的。
在你的语境中这样使用:
缺点:
data
对象中创建了很多空字典。这应该不是问题(除非你的内存非常低),因为对象不会被转储到一个文件中(不存在的值会出现在那里)0
或空列表,or
操作符将选择""
。这可以通过另一个 Package 器来测试对象是否为空superdefaultdict
来解决。不太优雅,但可行。第二种方法
将连续字典的访问转换为字符串(例如,将表达式(如
"['sql']['busData'][0]['engine']['engType']"
)用双引号括起来,解析它,然后循环键以获取数据。如果出现异常,则停止并返回空字符串。使用一些简单数据进行测试:
我们得到空字符串(缺少一些键),12(路径有效),空字符串(我们试图遍历一个非dict的现有值)。
语法可以简化(例如:
"sql"."busData".O."engine"."engType"
),但仍必须保留区分键(字符串)和索引(整数)的方法第二种方法可能是最灵活的。