Sie könnten getzweimal verwenden:
example_dict.get('key1', {}).get('key2')
Dies wird zurückgegeben, Nonewenn eines vorhanden ist key1oder key2nicht.
Beachten Sie, dass dies immer noch ein AttributeErrorif example_dict['key1']auslösen kann, aber kein Diktat (oder ein diktatähnliches Objekt mit einer getMethode) ist. Der try..exceptCode, den Sie gepostet haben, würde TypeErrorstattdessen ein if auslösenexample_dict['key1'] abonnierbar ist.
Ein weiterer Unterschied besteht darin, dass die try...exceptKurzschlüsse unmittelbar nach dem ersten fehlenden Schlüssel erfolgen. Die Anrufkette getnicht.
Wenn Sie die Syntax beibehalten möchten, example_dict['key1']['key2']aber nicht möchten, dass KeyErrors jemals ausgelöst wird, können Sie das Hasher-Rezept verwenden :
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'>
Beachten Sie, dass dies einen leeren Hasher zurückgibt, wenn ein Schlüssel fehlt.
Da Hasheres sich um eine Unterklasse von dictIhnen handelt, können Sie einen Hasher genauso verwenden wie einen dict. Es stehen dieselben Methoden und Syntax zur Verfügung. Hashers behandeln fehlende Schlüssel nur unterschiedlich.
Sie können eine reguläre dictin eine Hashersolche umwandeln :
hasher = Hasher(example_dict)
und konvertieren Sie ein Hasherin ein reguläres dictgenauso einfach:
regular_dict = dict(hasher)
Eine andere Alternative besteht darin, die Hässlichkeit in einer Hilfsfunktion zu verbergen:
def safeget(dct, *keys):
for key in keys:
try:
dct = dct[key]
except KeyError:
return None
return dct
Der Rest Ihres Codes kann also relativ lesbar bleiben:
safeget(example_dict, 'key1', 'key2')