2020-03-03 09:57:50 +00:00
|
|
|
'''
|
|
|
|
Overall, I like types.SimpleNamespace. But I decided to make dotdict because:
|
|
|
|
1. SimpleNamespace is a cumbersome name to type and to look at.
|
|
|
|
2. I wanted my class to support default values.
|
|
|
|
'''
|
2020-02-19 21:11:26 +00:00
|
|
|
from voussoirkit import sentinel
|
|
|
|
|
|
|
|
NO_DEFAULT = sentinel.Sentinel('NO_DEFAULT')
|
|
|
|
|
|
|
|
class DotDict:
|
2020-03-11 04:04:49 +00:00
|
|
|
def __init__(self, __dict=None, *, default=NO_DEFAULT, **kwargs):
|
2020-02-19 21:11:26 +00:00
|
|
|
self.__default = default
|
2020-03-11 04:04:49 +00:00
|
|
|
if __dict:
|
|
|
|
self.__dict__.update(__dict)
|
2020-02-19 21:11:26 +00:00
|
|
|
self.__dict__.update(**kwargs)
|
|
|
|
|
|
|
|
def __getattr__(self, key):
|
|
|
|
try:
|
|
|
|
return self.__dict__[key]
|
|
|
|
except KeyError:
|
|
|
|
if self.__default is not NO_DEFAULT:
|
|
|
|
return self.__default
|
|
|
|
raise
|
|
|
|
|
|
|
|
def __setattr__(self, key, value):
|
|
|
|
self.__dict__[key] = value
|
|
|
|
|
|
|
|
def __repr__(self):
|
2020-03-11 04:04:14 +00:00
|
|
|
display = self.__dict__.copy()
|
|
|
|
display.pop('_DotDict__default')
|
|
|
|
return f'DotDict {display}'
|