vinegar.utils.smart_dict
Provides a dictionary that has a smart get method.
The get method of SmartLookupDict is implemented in a way that makes it
easy to look for values in nested dictionaries.
For example, take a dictionary with the following content:
{'key1': {'key2': {'key3': 'value'}}}
In order to get the nested value, one would ordinarily have to use one of the two following expressions:
value = regular_dict['key1']['key2']['key3']
value = regular_dict.get('key1').get('key2').get('key3')
This is particularly bothersome if one cannot be sure that the nested value
even exists. In order to use a default value if one of the keys is missing, one
could use nested calls to get with default values:
value = regular_dict.get(
'key1', {}).get('key2', {}).get('key3', 'default value')
An alternative would be catching the KeyError:
try:
value = regular_dict['key1']['key2']['key3']
catch KeyError:
value = "default value"
Both alternatives are not very user friendly, in particular if used from a
template language where a try...catch construct might not be available.
The smart dictionaries make such use cases either by enabling the user to get a
nested value in a single call to get:
value = smart_dict.get('key1:key2:key3', 'default value')
By default the colon (:) is used as the key separator, but this can be
changed by specifying the sep argument:
value = smart_dict.get('key1_key2_key3', 'default value', sep='_')
In addition to handling nested dicts, the smart-lookup dict can also handle nested lists. For example, consider a dictionary with the following content:
{‘key1’: [‘a’, ‘b’, {‘nested_key’: 123}]}
The nested values can be looked up in the following way:
smart_dict.get(‘key1:0’) smart_dict.get(‘key1:2:nested_key’)
In addition to the get method, the setdefault method is overriden, so
that it automatically inserts nested dictionaries if needed. Please note that
setdefault can handle traversing lists, but it cannot handle inserting a
new item into a list.
The implementation of get provided by the smart lookup dictionaries also
differs from the one for regular dictionaries in that it do not use a default
value of None by default. Instead, it raises a KeyError if the key is
not found and no default value is provided.
- class vinegar.utils.smart_dict.SmartLookupDict
Dict that allows easy lookup and setting of nested values.
- get(key, *args, **kwargs)
Return the value for
key.If
keyis not in the dictionary anddefaultis given, returndefault. Ifdefaultis not given raise aKeyError.The
keycan be a nested key into nested dictionaries inside this dictionary. Thekeyis split using thesep(default:) and each component is used as the key on one level of nested dictionaries, the first component being used at the top level.- Parameters:
key – key for which the value shall be looked up. This can be a nested key into nested dictionaries.
sepis used to separate components of the key.default – default value to be returned if this dictionary (or one of the nested dictionaries) does not contain
key. If not specified, aKeyErroris raised instead.sep – separator separating components in
key. The default is:.
- Returns:
value for
keyordefaultif specified andkeyis not found.
- setdefault(key, default=None, sep=':', dict_type=<class 'dict'>)
Return the value for
keyinserting and returningdefaultifkeydoes not exist yet.The
keycan be a nested key into nested dictionaries inside this dictionary. Thekeyis split using thesep(default:) and each component is used as the key on one level of nested dictionaries, the first component being used at the top level.If one of the key components except the last key component is not found, a new dictionary of type
dict_typeis inserted automatically.- Parameters:
key – key for which the value shall be looked up. This can be a nested key into nested dictionaries.
sepis used to separate components of the key.default – default value to be inserted and returned if this dictionary (or one of the nested dictionaries) does not contain
key.dict_type – the type of dictionary that is created when a new dictionary has to be inserted. The default is
dict.
- Returns:
value for
keyordefaultifkeyis not found.