Skip to content Skip to sidebar Skip to footer

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"