Vous pouvez utiliser get
deux fois:
example_dict.get('key1', {}).get('key2')
Cela reviendra None
si l'un key1
ou l' autre key2
n'existe pas.
Notez que cela peut toujours déclencher un AttributeError
if example_dict['key1']
existe mais n'est pas un dict (ou un objet de type dict avec une get
méthode). Le try..except
code que vous avez publié lèverait un à la TypeError
place s'il example_dict['key1']
est désinscriptible.
Une autre différence est que les try...except
court-circuits immédiatement après la première clé manquante. La chaîne d' get
appels ne le fait pas.
Si vous souhaitez conserver la syntaxe, example_dict['key1']['key2']
mais ne voulez pas qu'elle déclenche jamais KeyErrors, vous pouvez utiliser la recette Hasher :
class Hasher(dict):
# https://stackoverflow.com/a/3405143/190597
def __missing__(self, key):
value = self[key] = type(self)()
return value
example_dict = Hasher()
print(example_dict['key1'])
# {}
print(example_dict['key1']['key2'])
# {}
print(type(example_dict['key1']['key2']))
# <class '__main__.Hasher'>
Notez que cela renvoie un Hasher vide lorsqu'une clé est manquante.
Depuis Hasher
une sous-classe de dict
vous pouvez utiliser un Hasher de la même manière que vous pourriez utiliser un dict
. Toutes les mêmes méthodes et syntaxe sont disponibles, les Hashers traitent simplement les clés manquantes différemment.
Vous pouvez convertir un régulier dict
en un Hasher
comme ceci:
hasher = Hasher(example_dict)
et convertissez a Hasher
en régulier dict
tout aussi facilement:
regular_dict = dict(hasher)
Une autre alternative est de cacher la laideur dans une fonction d'assistance:
def safeget(dct, *keys):
for key in keys:
try:
dct = dct[key]
except KeyError:
return None
return dct
Ainsi, le reste de votre code peut rester relativement lisible:
safeget(example_dict, 'key1', 'key2')