У меня есть произвольно вложенный json. Я хочу получить некоторое значение, которое имеет несколько ключей, и не имеет гарантии, что любой из ключей присутствует.
Так, например, я могу захотеть получить value = json_dict['a'][1]['q']['e']
но в любой момент я могу получить KeyError, если a
, q
или e
не существует или ошибка индекса за пределами границ, если json_dict['a']
имеет менее двух элементов. Если какое-либо из этих условий истинно, я хочу, чтобы value
было value
по умолчанию, есть ли способ сделать это, это одна или две строки без необходимости вставлять кучу операторов if или get
вызовы?
Вы можете поместить простую чистую версию python вместе:
def get_path(data, path, default=None):
try:
for item in path:
data = data[item]
return data
except (KeyError, TypeError, IndexError):
return default
nice_data = {'a': [None, {'q': {'e': 'Hello!'}}]}
bad_data = {'a': 6}
path = ['a', 1, 'q', 'e']
print('Good', get_path(nice_data, path)) # Hello!
print('Bad', get_path(bad_data, path)) # None
Не супер фантазия, но она работает.
Если вы хотите сделать что-то в одной меньшей строке, с немного большей мощностью, мы можем использовать что-то вроде ObjectPath (https://pypi.org/project/objectpath/):
from objectpath import Tree
def get_object_path(data, path, default=None):
try:
return Tree(data).execute(path)
except (KeyError, TypeError, IndexError):
return default
path = '$.a[1].q.e'
print('Good', get_object_path(nice_data, path))
print('Bad', get_object_path(bad_data, path))
Нам еще предстоит обработать свою собственную обработку ошибок, и она будет намного медленнее, но она может поддерживать всевозможные причудливые запросы (из документов):
In weather readings find cities where temperature is higher than 25°C and the sky is clear.
$..*[@..temp > 25 and @.clouds.all is 0].name
IndexError
вы не должны кроме IndexError
s?