Double underscore in python

class A(object): def __get(self): pass def _m(self): return self.__get() class B(A): def _m(self): return str(self.__get()) print(A()._m()) print(B()._m()) 

Why print(A()._m()) print None , but print(B()._m()) raises AttributeError: 'B' object has no attribute '_B__get' ?

I thought double underscore prevents method overriding.

UPDATE

You write that __get is private.

Then why does the following work?

 class A(object): def __get(self): pass def _m(self): return self.__get() class B(A): pass print(A()._m()) print(B()._m()) 

Why doesn't this code raise an AttributeError and print None twice?

+8
python
source share
1 answer

private double underscore names (meaning inaccessibility for derived classes)

This is not reliable. It is implemented by changing the name. The Python documentation says:

Any identifier of the __spam form (at least two leading underscores, no more than one underscore) is replaced with the text _classname__spam, where classname is the current class name with separator underscores. This manipulation is performed regardless of the syntactic position of the identifier, so it can be used to define a class-private instance and class variables, methods, variables stored in global tables, and even variables stored in instances. This class is private on instances of other classes.

Thus, __get is actually distorted to _A__get in class A. When class B tries to reference __get , it becomes distorted until _B__get , which does not match.

In other words, __plugh defined in the Xyzzy class means "if you are not working as an Xyzzy class, do not touch __plugh."

+7
source share

All Articles