def __getattr__(self, attr): """When attribute is not found in the class, Python looks for this special method, so "self.inexistent" will get here and so we can forward it to the __getitem__ self['inexistent'] and then the defaultdict can return a new empty node, but if it starts with _ it is treated as a normal attribute like _strategy, _store, _value """ if not attr.startswith('_'): return self[attr] return defaultdict.__getattribute__(self, attr)
def __getattribute__(self, item): # noqa """This method is called for every dotted access so we can control special names like the ones in the list below: copy,update,values,clear,get,items that names are reserved because can be a locator name and also a method of this object""" reserved_names = ('copy', 'update', 'values', 'clear', 'get', 'items') if item in reserved_names and item in self: return self.__getitem__(item) return defaultdict.__getattribute__(self, item)