What is the difference between the two class definitions below,
class my_dict1(dict):
def __init__(self, data):
self = data.copy()
self.N = sum(self.values)
The above code results in AttributeError: 'dict' object has no attribute 'N'
, while the below code compiles
class my_dict2(dict):
def __init__(self, data):
for k, v in data.items():
self[k] = v
self.N = sum(self.values)
For example,
d = {'a': 3, 'b': 5}
a = my_dict1(d) # results in attribute error
b = my_dict2(d) # works fine
By assigning self
itself to anything you assign self
to a completely different instance than you were originally dealing with, making it no longer the "self". This instance will be of the broader type dict
(because data
is a dict
), not of the narrower type my_dict1
. You would need to do self["N"]
in the first example for it to be interpreted without error, but note that even with this, in something like:
abc = mydict_1({})
abc
will still not have the key "N" because a completely difference instance in __init__
was given a value for the key "N". This shows you that there's no reasonable scenario where you want to assign self
itself to something else.
In regards to my_dict2
, prefer composition over inheritance if you want to use a particular dict
as a representation of your domain. This means having data
as an instance field. See the related C# question Why not inherit from List?, the core answer is still the same. It comes down to whether you want to extend the dict
mechanism vs. having a business object based on it.