Search code examples
pythoninheritanceoverridingparent

How do I override a parent class's functions in python?


I have a private method def __pickSide(self): in a parent class that I would like to override in the child class. However, the child class still calls the inherited def __pickSide(self):. How can I override the function? The child class's function name is exactly the same as the parent's function name.


Solution

  • Let's look at the easiest example:

    from dis import dis
    
    class A(object):
      def __pick(self):
          print "1"
    
      def doitinA(self):
          self.__pick()
    
    class B(A):
      def __pick(self):
          print "2"
    
      def doitinB(self):
          self.__pick()
    
    b = B()
    b.doitinA() # prints 1
    b.doitinB() # prints 2
    
    dis(A.doitinA)
    print
    dis(B.doitinB)
    

    The disassembly is as follows:

      8           0 LOAD_FAST                0 (self)
                  3 LOAD_ATTR                0 (_A__pick)
                  6 CALL_FUNCTION            0
                  9 POP_TOP
                 10 LOAD_CONST               0 (None)
                 13 RETURN_VALUE
    
     15           0 LOAD_FAST                0 (self)
                  3 LOAD_ATTR                0 (_B__pick)
                  6 CALL_FUNCTION            0
                  9 POP_TOP
                 10 LOAD_CONST               0 (None)
                 13 RETURN_VALUE
    

    As you can see, Python mangles function names that begin with two underscores (and accesses to such names!!) to a name that includes the class name - in this case _A__pick and _B__pick). That means that the class in which a function is defined determines which of the __pick methods is called.

    The solution is simple, avoid pseudo-private methods by removing the double underscores. For example, use _pick instead of __pick.