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:

>>> 2

But if I do:

>>> 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?

5 Years
Discussion Span
Last Post by slate

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 """

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 by slate

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.