Skip to content

Instantly share code, notes, and snippets.

@Jasata
Last active December 29, 2019 19:13
Show Gist options
  • Save Jasata/d4b9959bbe7f0ebd8bdb3f21a836ea36 to your computer and use it in GitHub Desktop.
Save Jasata/d4b9959bbe7f0ebd8bdb3f21a836ea36 to your computer and use it in GitHub Desktop.
Dot-access dictionary with default value
#! /usr/bin/env python3
# 2019-12-28 Jani Tammi
#
# Slightly improved DefaultDotDict, using '*' as default value.
# NOTE: DefaultDotDict.get('foobar') does NOT return value for key '*'.
# You still get to define your own default value.
#
class DefaultDotDict(dict):
"""Dot-notation access dict with default key '*'. Returns value for key '*' for missing missing keys, or None if '*' value has not been set."""
def __custom_get__(self, key):
"""For all DotDict.key access, missing or otherwise."""
return self.get(key, self.get('*', None))
__getattr__ = __custom_get__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
def __missing__(self, key):
"""For DefaultDotDict[key] access, missing keys."""
return self.get('*', None)
a = DefaultDotDict(
{
'teacher': ['anyone', 'student', 'teacher'],
'student': ['anyone', 'student'],
'*': ['anyone']
}
)
# Alternate create style
b = DefautlDotDict(
teacher = ['anyone', 'student', 'teacher'],
student = ['anyone', 'student']
)
# The clumsy thing is that you cannot create '*' key in the above, and need to do this separately:
b['*'] = ['anyone']
print("a.teacher ", a.teacher)
print("a.student ", a.student)
print("a.get('student') ", a.get('student'))
print("a['student'] ", a['student'])
print("a.get('*') ", a.get('*'))
print("a['*'] ", a['*'])
print("a['bozo'] ", a['bozo'])
print("a.bozo_the_clown ", a.bozo_the_clown)
print("a.get('clown', ['!'])", a.get('clown', ['!']))
# EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment