I am building a class which subclasses dict
, and overrides __setitem__
. I would like to be certain that my method will be called in all instances w
I found Ian answer and comments very helpful and clear. I would just point out that maybe a first call to the super-class __init__
method might be safer, when not necessary: I recently needed to implement a custom OrderedDict (I'm working with Python 2.7): after implementing and modifying my code according to the proposed MyUpdateDict
implementation, I found out that by simply replacing
class MyUpdateDict(dict):
with:
from collections import OrderedDict
class MyUpdateDict(OrderedDict):
then the test code posted above failed:
Traceback (most recent call last):
File "Desktop/test_updates.py", line 52, in
my_dict = MyUpdateDict([('b',2),('c',3)],a=1)
File "Desktop/test_updates.py", line 5, in __init__
self.update(*args, **kwargs)
File "Desktop/test_updates.py", line 18, in update
self[key] = other[key]
File "Desktop/test_updates.py", line 9, in __setitem__
super(MyUpdateDict, self).__setitem__(key, value)
File "/usr/lib/python2.7/collections.py", line 59, in __setitem__
root = self.__root
AttributeError: 'MyUpdateDict' object has no attribute '_OrderedDict__root'
Looking at collections.py code it turns out that OrderedDict needs its __init__
method to be called in order to initialize and setup necessary custom attributes.
Therefore, by simply adding a first call to the super __init__
method,
from collections import OrderedDict
class MyUpdateDict(Orderedict):
def __init__(self, *args, **kwargs):
super(MyUpdateDict, self).__init__() #<-- HERE call to super __init__
self.update(*args, **kwargs)
we have a more general solution which apparently works for both dict and OrderedDict.
I cannot state if this solution is generally valid, because I tested it with OrderedDict only. However, it is likely that a call to the super __init__
method is either harmless or necessary rather than harmful, when trying to extend other dict subclasses