Ответ 1
Как я писал и оформлял вопрос, я нашел ответ (бывает со мной много). Может быть, это может помочь кому-то другому.
Решение для меня было следующим:
def __getattr__ ( self, attr : str ) -> str:
return self.__getitem__(attr)
def __setattr__ ( self, attr : str, val : str ) -> None:
if attr == 'store':
super().__setattr__(attr,val)
else:
self.__setitem__(attr,val)
Ключ состоит в том, что атрибут store
должен быть отделен и вызван из базового класса, чтобы избежать рекурсии. Довольно просто, но мне было легко пропустить!
UPDATE:
Я добавил функциональность для добавления атрибутов, которые вы не хотите хранить в store
(т.е. обычном значении атрибутов). Я также реализовал store
как OrderedDict
, но это только для моего прецедента. Очевидно, исключение set_inst_attr
является временным/заполнителем.
from collections import MutableMapping, OrderedDict
class ODictish (MutableMapping):
"""
An OrderedDict-like mapping object.
Provides __getattr__ and __setattr__ as aliases for __getitem__
and __setitem__.
Attributes which you do not want to keep in 'store' can be set with
self.set_inst_attr.
"""
def __init__ ( self , od=None):
if od is None: od = OrderedDict()
super().__setattr__('store', OrderedDict(od))
def __getitem__ ( self, key ):
return self.store[key]
def __setitem__ ( self, key, val ):
self.store[key] = val
def __delitem__ ( self, key ):
del self.store[key]
def __iter__ ( self ):
return iter(self.store)
def __len__ ( self ):
return len(self.store)
def __repr__ ( self ):
return repr(self.store)
def __getattr__ ( self, attr ):
if attr in vars(self):
return vars(self)[attr]
return self.__getitem__(attr)
def __setattr__ ( self, attr, val ):
if attr in vars(self):
self.set_inst_attr(attr,val)
else:
self.__setitem__(attr,val)
def set_inst_attr ( self, attr, val ):
if attr == 'store':
raise Exception("Don't do that.")
super().__setattr__(attr,val)
def move_to_end ( self, key, last=True ):
self.store.move_to_end(key,last)