Implementing A Dict-like Object With __getattr__ And __setattr__ Functionality
I'm trying to implement a dict-like object which can be accessed/modified with __getattr__ and __setattr__ for ease of use for my users. The class also implements some other simple
Solution 1:
As I was writing and formalizing the question, I found the answer (happens to me a lot). Maybe this can help someone else.
The solution for me was the following:
def __getattr__ ( self, attr : str ) ->str:
returnself.__getitem__(attr)
def __setattr__ ( self, attr : str, val : str ) ->None:
if attr == 'store':
super().__setattr__(attr,val)
else:
self.__setitem__(attr,val)
The key is that the store
attribute must be separated out and called from the base class to avoid recursion. Pretty simple but was easy for me to miss!
UPDATE:
I added functionality for adding attributes that you do not want to keep in store
(ie. the usual meaning of attributes). I also implemented store
as an OrderedDict
, but this is just for my use-case. Obviously the set_inst_attr
exception is temporary/a placeholder.
from collections import MutableMapping, OrderedDict
classODictish (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 isNone: 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 ):
returniter(self.store)
def__len__ ( self ):
returnlen(self.store)
def__repr__ ( self ):
returnrepr(self.store)
def__getattr__ ( self, attr ):
if attr invars(self):
returnvars(self)[attr]
return self.__getitem__(attr)
def__setattr__ ( self, attr, val ):
if attr invars(self):
self.set_inst_attr(attr,val)
else:
self.__setitem__(attr,val)
defset_inst_attr ( self, attr, val ):
if attr == 'store':
raise Exception("Don't do that.")
super().__setattr__(attr,val)
defmove_to_end ( self, key, last=True ):
self.store.move_to_end(key,last)
Post a Comment for "Implementing A Dict-like Object With __getattr__ And __setattr__ Functionality"