解析大型 JSON 时,某些键可能仅在某些情况下存在,例如出现错误时。从服务器的 API 获取
200 OK
的情况并不少见,但是您得到的响应包含应检查的错误。
处理此问题的最佳方法是什么?
我知道使用类似 || 之类的东西。 |是处理 KeyError 的一种方法。
get()
但是如果我们需要继续下去怎么办?这感觉太可怕了:
if json.get('errors') is not None:
do_something
有更好的方法吗?例如,
if json.get('errors') is not None:
if json.get('errors').get('code') is not None:
if json.get('errors').get('code') != 0:
this_is_bad_throw_error
有一个
ruby
方法,基本上将整行压缩为
dig()
,然后您只需检查
x = dig(:errors, :code)
是否是
x
对象;所以 2 行,而不是 4 行(或者更多,如果你必须继续深入的话)。
nil
我之前用过
来捕捉
try-except
,但这不是我一定关心的方法。|| |我并不反对外部库,但由于代码运行的位置,坚持使用内置库是非常有利的。
KeyError
, but this isn't an approach I necessarily care for.
I'm not against external libraries, but due to the location of where the code is being run it's extremely beneficial to stick to built-ins.
在 Python 中遍历字典并同时避免
KeyError
的最佳方法有几种,具体取决于的代码风格和目标。以下是一些选项:
1. get() 方法及其替代方法
提到了
get()
方法,这是一个很好的开始。它允许指定一个默认返回值(默认为
None
),如果找不到该键,则返回该值。可以链接
get()
调用以深入嵌套字典,但正如所指出的,这可能会变得冗长。
这是一个更简洁的替代方案,它使用短路评估:
error_code = json.get('errors') and json.get('errors').get('code')
if error_code and error_code != 0:
# 处理错误
在这个例子中,如果
json.get('errors')
返回一个真值(例如,一个非空字典),那么表达式将继续求值到
json.get('errors').get('code')
。如果第一个
get()
返回
None
,则整个表达式将短路为
None
,而不会引发
KeyError
。
2. try-except 块(带有改进)
虽然提到不太喜欢
try-except
块,但它们可以非常有效且易读,尤其是在处理多个嵌套键时。 以下是如何改进它们以提高可读性的方法:
try:
error_code = json['errors']['code']
if error_code != 0:
# 处理错误
except KeyError:
# 处理缺少的键
此方法尝试直接访问嵌套键。 如果任何键不存在,则会引发
KeyError
,并且代码会执行
except
块。
3. 自定义“dig”函数
如果喜欢 Ruby 的
dig
方法,可以轻松地在 Python 中创建自己的版本:
def dig(data, *keys):
for key in keys:
if isinstance(data, dict) and key in data:
data = data[key]
else:
return None
return data
error_code = dig(json, 'errors', 'code')
if error_code and error_code != 0:
# 处理错误
此函数接受一个数据结构(例如的 JSON 字典)和任意数量的键。 它迭代这些键,并尝试在每一步深入到嵌套的数据结构中。 如果在任何时候找不到键或数据结构不是字典,它将返回
None
。
选择正确的方法
最终,选择最适合的方法取决于的具体需求和偏好。
-
如果只需要检查几个嵌套键,
get()
方法及其短路评估变体提供了一种简洁易读的解决方案。 -
如果需要处理多个嵌套键或执行更复杂的错误处理,
try-except
块提供了一种更结构化且可能更易读的方法。 -
如果发现自己在多个地方需要这种“深度挖掘”功能,那么创建自定义
dig
函数可以提高代码的可重用性和可读性。