Dill
Dill

Reputation: 2025

subclassing collections.abc.MutableMapping - update method

I try to understand subclassing of collections.abc.MutableMapping. I've created my own version of dict that prints some info:

from collections.abc import MutableMapping

class MutableMappingTest(MutableMapping):

    def __init__(self, *args, **kwargs):
        print('__init__', args, kwargs)
        self.my_store = dict()
        self.update(dict(*args, **kwargs))

    def __getitem__(self, key):
        print('__getitem__:', key)
        return self.my_store[key]

    def __setitem__(self, key, value):
        print('__setitem__:', key, value)
        self.my_store[key] = value

    def __delitem__(self, key):
        print('__delitem__:', key)
        del self.my_store[key]

    def __iter__(self):
        print('__iter__')
        return iter(self.my_store)

    def __len__(self):
        print('__len__')
        return len(self.my_store)

What I do not understand: When I update by assigning to a nested attribute, __setitem__ is not called, just __getitem__:

>>> t = MutableMappingTest(test={"deep": "foo"})
__init__ () {'test': {'deep': 'foo'}}
__setitem__: test {'deep': 'foo'}
>>> t['test']['deep'] = 'bar'
__getitem__: test

How can I also hook into updating nested attributes. Do I have to override update()? How is that done?

Upvotes: 0

Views: 1161

Answers (1)

Patrick Haugh
Patrick Haugh

Reputation: 60974

Because you're not setting an item in t. Instead, you're getting a regular dictionary from t, and then setting an item in that dictionary.

If you want the sub dictionaries to behave like MutableMappingTest objects, you have to make them MutableMappingTest objects.

>>> t = MutableMappingTest(test=MutableMappingTest(deep="foo"))
__init__ () {'deep': 'foo'}
__setitem__: deep foo
__init__ () {'test': <__main__.MutableMappingTest object at 0x000001EA3C1DDB00>}
__setitem__: test <__main__.MutableMappingTest object at 0x000001EA3C1DDB00>
>>> t['test']['deep'] = 'bar'
__getitem__: test
__setitem__: deep bar

Upvotes: 1

Related Questions