pythoninheritancepython-3.xmember-hiding

Python: Hide member of base class in derived class


How to override a member of base class in my derived class so that accesses to such member cause invoking the derived member? Consider folllowing example? __tmp is overwritten in B and should be return in case of a call to tmp()

class A:
    __tmp = {"A" : 1,
             "B" : 2}
    def tmp(self):
        return self.__tmp

class B(A):
    __tmp = {"A" : 10,
             "B" : 20}
    def __init__(self):
        super().__init__()

b = B()
print(b.tmp()) # Expect to print {'A': 10, 'B': 20} here

Solution

  • Don't use obfuscated variable names:

    class A:
        _tmp = {"A" : 1,
                 "B" : 2}
        def tmp(self):
            return self._tmp
    
    class B(A):
        _tmp = {"A" : 10,
                 "B" : 20}
        def __init__(self):
            super().__init__()
    
    b = B()
    print(b.tmp()) # Works as expected
    

    The problem was that self.__tmp is name-mangled behind the scenes by python and resolves to self._A__tmp since tmp is a method of the A class. You wanted self._B__tmp. If you had redefined the tmp method in B it would have worked, but that's a silly way of doing it, since it defeats one of the purposes of inheritance -- avoiding code duplication.

    Reserve the use of __private variables for when you wish to avoid name clashes with the attributes of subclasses. In this case, you really wish to achive such a naming collition.

    If you want to make an attribute private, it suffices with a single underscore, since we're all consenting adults here.