I came across this question of trying to implement a dictionary using the collections.abc MutableMapping because I was looking for something similar.
For context, I was looking to implement a dictionary that would out of convenience also act as a mutable object so if I write this for example d = CustomDictionary({'a': 4})
then d.a
returns 4.
For reference, here is the code posted by Aaron Hall for this particular problem:
from collections.abc import MutableMapping
class D(MutableMapping):
'''
Mapping that works like both a dict and a mutable object, i.e.
d = D(foo='bar')
and
d.foo returns 'bar'
'''
# ``__init__`` method required to create instance from class.
def __init__(self, *args, **kwargs):
'''Use the object dict'''
self.__dict__.update(*args, **kwargs)
# The next five methods are requirements of the ABC.
def __setitem__(self, key, value):
self.__dict__[key] = value
def __getitem__(self, key):
return self.__dict__[key]
def __delitem__(self, key):
del self.__dict__[key]
def __iter__(self):
return iter(self.__dict__)
def __len__(self):
return len(self.__dict__)
# The final two methods aren't required, but nice for demo purposes:
def __str__(self):
'''returns simple dict representation of the mapping'''
return str(self.__dict__)
def __repr__(self):
'''echoes class, id, & reproducible representation in the REPL'''
return '{}, D({})'.format(super(D, self).__repr__(),
self.__dict__)
However I didn't consider the dangers of doing so. Namely, if I created this custom dictionary class then I would expect to have methods. But what if a method name clashes with a key with the same name? For example:
def doSomething(self):
""" A method of CustomDictionary"""
print("hey!")
d = CustomDictionary()
d['a'] = 3
d['doSomething'] = 4
d.doSomething()
would raise a TypeError: 'int' object is not callable
since d.doSomething
would return 4 which is not a callable function.
What do you think? How would I go about implementing methods for a custom dictionary class while avoiding this problem.
Unfortunately I couldn't comment on the post since I don't have enough reputation but I was hoping this question deserves its own post.