From the docs:
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. Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.
My interpretation:
Mangling the name of a parent class method
parent.__m(a, b)
to allow a child to overload it with extra parameterschild.m(a, b, c)
. This way when you callchild.m(1, 2, 3)
, the extra parameter isn't being passed to the parent class and confusing it.Mangling isn't necessary if you plan on keeping the same method signature but changing some of the internal functionality. You can still access the old functionality by using
super()
.In summary if you want the ability to overload a class method in the future, mangle it. Otherwise, it's not necessary.
Question:
Is my summary correct? The docs are poorly written. Lots of run-on sentences and midstream (asides) that muddle my ability to determine if I've understood correctly.
Edit: I just played with some code:
class Parent( object ):
def __init__(self, a, b):
self.a = a
self.b = b
def method( self ):
return 1
class Child(Parent):
def __init__(self, a, b, c ):
super().__init__(a, b)
def method(self, c):
field = [c]
return field
a, b, c = 0, 1, 2
c = Child(a, b, c)
print(c)
This works well enough. The only issue I ran into is if I do something like this:
class Parent( object ):
def __init__(self, a, b):
self.a = a
self.b = b
self.c = self.method()
def method( self ):
return 1
class Child(Parent):
def __init__(self, a, b, c ):
super().__init__(a, b)
self.c = self.method(c)
def method(self, c):
field = [c]
return field
a, b, c = 0, 1, 2
c = Child(a, b, c)
Which returns
TypeError: method() missing 1 required positional argument: 'c'
This is discussed in this answer: Python, Overriding an inherited class method
So at the end of the day it looks like I still don't understand what the purpose is.