Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclassing from Dict violates basic rule of object oriented programming in python

Tags:

python

oop

I am requesting better insights on the author's comments for a particular section of code. To go much in detail, I will illustrate with an example.

 class DoppelDict(dict):           
     def __setitem__(self, key, value):
        super().__setitem__(key, [value] * 2)

 # case 1.
 dd = DoppelDict(one=1)
 print(dd)  # {'one':1}

 # case 2.
 dd['two'] = 2
 print(dd)  # {'one':1,'two':[2,2]}

The above example is picked from a book and the author comments 'Built-in behavior is a violation of a basic rule of object-oriented programming: the search for methods should always start from the class of the target instance (self), even when the call happens inside a method implemented in a superclass'.

I believe the author is trying to convey since python ignores special methods overridden by user-defined class, it is a violation of OOP. I wanted to know whether my explanation is correct?. Do you have any other explanation to author comments?.

like image 229
James K J Avatar asked Mar 05 '23 15:03

James K J


1 Answers

I can't really comment on the "Built-in behavior is a violation of a basic rule of object-oriented programming:". But in your code there are two separate and very different things happening.

When you do

dd = DoppelDict(one=1)

This looks for __init__ in the MRO and since your class didn't override __init__ and so __init__ method of the super class which is dict is called.

However when you do

dd['two'] = 2

python looks for __setitem__ method in the MRO which you have overriden and hence it is called and you get the expected result.

Its all related to super and MRO. You can easily look at the MRO for any class by simply checking __mro__ attribute.

In[5]: a = 100
In[6]: a.__class__.__mro__
Out[6]: (int, object)

The above example is just for an builtin class but the same applies to any other custom class as well.

like image 59
Rohit Avatar answered Apr 27 '23 16:04

Rohit