Hi. I have a Foo class that stored a dictionary attribute called _data. I'd like the Foo class to have a dictionary interface, and defer most basic dictionary operations down to the _data attribute.

I am currently overwriting the magic methods one by one:

def __getitem__(self, item):
    return self._data[item]

def __delitem__(self, item):
    del self._data[item]

def __len__(self):
    return self._data.__len__

def __iter__(self):
    return self._data.__iter__

def __reversed__(self):
    return self._data.__reversed__        

It seems like there should be an easier way to do this. I tried the following:

_magic=['__len__', '__iter__', '__reversed__', '__contains__']

def __assign_magic(self):
    for meth in self._magic:
        setattr(self, meth, getattr(self._data, meth))

This works to an extent. For example, I can do:

f=Foo()
f.__len__()
>>> 2

But if I do:

len(f)
>>> TypeError: object of type 'Foo' has no len()

Why does python not see the len() magic method, and is there a way to get it to?

Would it not be easier to make Foo a decendent of dict? Then you have all of those by default.

class Foo(dict)
    """ More code here """
    pass

Your delegation is not working because Foo().__len__ is called with Foo() as self and not with Foo()._data as self.

There are many ways to mix two classes.
Let say you have two classes. One is a dictionary like object, another with some bussiness functionality. You want the two classes in one.

  • You can inherit from both the dictionary and the bussiness class.
  • You can use composition and delegate the dictionary interface to the dictionary singleton. That is what you are trying.
  • You can use composition and delegate the bussiness interface to the bussiness singleton. That is what zjtpjs is saying.
  • You can use composition and delegate to both

If you just mechanically delegate to the underlying dict object, then inheritance is suitable for you.

Edited 3 Years Ago by slate

This article has been dead for over six months. Start a new discussion instead.