Question

So I have essentially created a dictionary Class that uses classmethods for all of its magic methods that looks like this:

class ClassDict(object):
    _items = {}

    @classmethod
    def __getitem__(cls, key):
        return cls._items[key]

    @classmethod
    def __setitem__(cls, key, val):
        cls._items[key] = val

    @classmethod
    def __len__(cls):
        return len(cls._items)

    @classmethod
    def __delitem__(cls, key):
        cls._items.__delitem__(key)

    @classmethod
    def __iter__(cls):
        return iter(cls._items)

And so when I try to assign an item to it:

ClassDict['item'] = 'test'

I get an error saying TypeError: 'type' object does not support item assignment, but if I call the actual method, __setitem__ like so it works fine:

ClassDict.__setitem__('item', 'test')

And this also works:

ClassDict().__setitem__('item', 'test')

Is there anything I am doing wrong here that would prevent the first example from working? Is there any way I can fix this issue?

Was it helpful?

Solution

To get the behavior desired of being able to do:

ClassDict['item'] = 'test'

I had to implement the special methods as a metaclass instead as Martijn pointed out.

So my final implementation looks like this:

class MetaClassDict(type):
    _items = {}

    @classmethod
    def __getitem__(cls, key):
        return cls._items[key]

    @classmethod
    def __setitem__(cls, key, val):
        cls._items[key] = val

    @classmethod
    def __len__(cls):
        return len(cls._items)

    @classmethod
    def __delitem__(cls, key):
        cls._items.__delitem__(key)

    @classmethod
    def __iter__(cls):
        return iter(cls._items)


class ClassDict(object):
    __metaclass__ = MetaClassDict
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top