【发布时间】:2023-02-16 01:26:51
【问题描述】:
我正在处理加载到 Python 词典中的 JSON 数据。其中很多都有可选字段,然后可能包含字典之类的东西。
dictionary1 =
{"required": {"value1": "one", "value2": "two"},
"optional": {"value1": "one"}}
dictionary2 =
{"required": {"value1": "one", "value2": "two"}}
如果我这样做,
dictionary1.get("required").get("value1")
显然,这是有效的,因为字段 "required" 始终存在。
但是,当我在 dictionary2 上使用同一行(以获取可选字段)时,这将产生一个 AttributeError
dictionary2.get("optional").get("value1")
AttributeError: 'NoneType' object has no attribute 'get'
这是有道理的,因为第一个 .get() 将返回 None,而第二个 .get() 不能在 None 对象上调用 .get()。
我可以通过提供默认值来解决这个问题,以防可选字段丢失,但是数据变得越复杂,这就越烦人,所以我称之为“天真的修复”:
dictionary2.get("optional", {}).get("value1", " ")
所以第一个.get() 将返回一个空字典{},可以在其中调用第二个.get(),并且由于它显然不包含任何内容,它将返回空字符串,如第二个默认值所定义的那样。
这将不再产生错误,但我想知道是否有更好的解决方案 - 特别是对于更复杂的情况(value1 包含一个数组或另一个字典等......)
我也可以用 try - 除了AttributeError 来解决这个问题,但这也不是我的首选方式。
try:
value1 = dictionary2.get("optional").get("value1")
except AttributeError:
value1 = " "
我也不喜欢检查可选字段是否存在,这会产生垃圾代码行,例如
optional = dictionary2.get("optional")
if optional:
value1 = optional.get("value1")
else:
value1 = " "
这似乎非常非Pythonic ...
我在想也许我只是链接 .get()s 的方法首先是错误的?
【问题讨论】:
-
为什么不喜欢 try-except 子句?这是处理此问题的最 pythonic 方式,也是最容易阅读的方式。
-
只是创建代码行......我想我正在寻找一个单行代码。 (代码中会布满 try-except 块)
-
@c8999c3f964f64 感谢您分享您的解决方案,但通常应将其作为答案发布,而不是对问题进行编辑。我删除了它,但随时将其作为答案发布。谢谢。
标签: python json dictionary attributeerror