3

I want need a virtual mechanism in Python and was implemented as below:

class A() :
    def __init__(self) :
        self.level()

    def level(self) :
        print("At level A")

class B(A)
    def level(self) :
        print("At level B")

It worked as expected:

>>>b = B()
At level B

Then I wanted to keep level() function in private by changing function's name into __level():

class A() :
    def __init__(self) :
        self.__level()

    def __level(self) :
        print("At level A")

class B(A)
    def __level(self) :
        print("At level B")

But it didn't work:

>>>b = B() 
At level A

The virtual mechanism magically lost when the function became private! Can someone help to explain why?

3
  • Use a single underscore to indicate "private." Two invokes name mangling. Commented Feb 11, 2017 at 5:03
  • @kindall But name mangling is exactly what makes the method private. Commented Feb 11, 2017 at 5:20
  • In any case, the fact that the name is mangled is why the method isn't being called. Commented Feb 11, 2017 at 5:30

1 Answer 1

1

Since there is a valid use-case for class-private members (namely to avoid name clashes of names with names defined by subclasses), there is limited support for such a mechanism, called name mangling.

Private Variables

class A() :
    def __init__(self) :
        self.__level()
        self._B__level()

    def __level(self) :
        print("At level A")

class B(A):
    def __level(self) :
        print("At level B")

In [228]: b=B()
At level A
At level B

Due to this mangling, the B version of __level can't be used from A methods (even if they are inherited by a B object). It has to use the mangled name explicitly. Breaking this 'virtual' function link (as you call it) is the purpose of mangling, as stated in the above clip.

In [232]: b._A__level()
At level A
In [233]: b._B__level()
At level B
In [234]: b.__level()
....
AttributeError: 'B' object has no attribute '__level'
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @hpaulj for patient explanation and example. The example leads to the philosophy of Python. There is probably no real private because we could still be able to access private by 'myclass._myclass_private'. Anything involving in the philosophy of a language, there is no right/wrong. Just have to adapt into it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.