Going through this complete tutorial, you will learn one of the very important concepts- Python Name Mangling.
It’s not so difficult as it seems to be if you follow this complete tutorial and executing the code I have shared in this tutorial.
Let’s begin.
Table of Contents
In Python programming, you can provide the access modifier (public/private) to the class members (variable or function).
Basically, an access modifier is used to define- whether the given to class members should be accessible to outside the class or not.
In most of the programming, if you mention access modifier as private for any class members, your program cannot access that class member outside of the class.
As Python doesn’t have an access modifier, you can not restrict the class members from getting access outside of the class.
To overcome this, Python has a concept Name Mangling.
Don’t bother. I will explain it in a very simple manner- step-by-step
Let’s take a simple class example to define the name mangling.
class myClass: def __init__(self): self.x=10 self.__y=20 obj=myClass() print(obj.__y)
You will get an error as
Traceback (most recent call last): File "/home/1af1225c50e8214f40613eda2aa27751.py", line 7, in <module> print(obj.__y) AttributeError: 'myClass' object has no attribute '__y'
Even though we have initialized __y
variable inside the __init__()
, you can not access it outside of the class using the object.
Adding __
as a prefix makes member private.
Why is there no attribute associated with the object obj
?
Let’s see all the attributes associated with the object obj
.
You can simply print all the attributes that correspond to the object using dir()
method.
Here is a simple program.
class myClass: def __init__(self): self.x=10 self.__y=20 obj=myClass() print(dir(obj))
Output.
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_myClass__y', 'x']
If you look at the output list, there is no attribute __y
. Whereas, attribute x
that we have initialized is present.
Interestingly, instead of __y
, you can find the attribute _myClass__y
.
While executing your program, the name of the attribute __y
is renamed to _myClass__y
.
Every attribute prefixed with __
(double underscores) will be changed to _<class_name><atribute_name>
This concept is called the name mangling in Python.
Here is your program. You can rewrite to access the name mangling attribute.
class myClass: def __init__(self): self.x=10 self.__y=20 obj=myClass() print(obj._myClass__y)
Output:
20
In the above example, I explained to you the name mangling for the variable attribute. This concept also holds true for the function name.
Python underscore prefix function.
Try this simple Python class function.
class myClass: def myFunc(self): print("Hello, World!") obj=myClass() obj.myFunc()
Output:
Hello, Wolrd!
Now rename function name from myFunc()
to __myFunc()
and run the program again.
class myClass: def __myFunc(self): print("Hello World!") obj=myClass() obj.__myFunc()
Output:
Traceback (most recent call last): File "/home/22c0364aa126811fe5f362040f5a1c91.py", line 7, in <module> obj.__myFunc() AttributeError: 'myClass' object has no attribute __myFunc
As you have given __
before the function name, as per the name mangling concept in Python, this function name is renamed to _myClass__myFunc()
.
class myClass: def __myFunc(self): print("Hello, World!") obj=myClass() obj._myClass__myFunc()
Output:
Hello, World!
Using inheritance, you can override the base class (parent class) function with a derived class (child class) function.
You can write a function with the same name in the parent as well as in the child’s class.
To avoid this ambiguity, you can add __
(double underscore) in front of the function name. With the Name Mangling mechanism, both the function will be renamed as below.
Name Mangling in the base class:
_<base_class_name>__<function_name>
Name Mangling in the derived class:
_<derived_class_name>__<function_name>
Now you can distinguish override function.
Function overriding without Name Managing.
class baseClass: def myFunc(self): print("I'm a parent.") class derivedClass(baseClass): def myFunc(self): print("I'm a child.") obj=derivedClass() obj.myFunc()
Output:
I'm a child.
Even though myFunc()
is defined in the base and derived class, the object of the derived class always calls the method from a derived class.
Function overriding with Name Mangling
class baseClass: def __myFunc(self): print("I'm a parent.") class derivedClass(baseClass): def __myFunc(self): print("I'm a child.") obj=derivedClass() obj._derivedClass__myFunc() obj._baseClass__myFunc()
Output:
I'm a child. I'm a Parent.
Now you can call the same method in the base class as well as in the derived class using the Name Mangling mechanism.
Summary
Some points to be remembered.
__
(double underscores)._
(single underscore), it will work as normal attribute._<class_name><atrribute>
. This format is used by a class object to access the attribute outside of the class.This concept is very important and was asked in many of the interviews. Check Name Mangling question asked in PwC interview round for Python developer.
This is all about Python Name Mangling. Any doubt? Let’s connect by writing in the comment. I will reply to every question.
Happy Pythoning!
This is an amazing concept and Explanation. Kudos to you ..!
Thanks, Rajeev! I’m glad you like it.
Explained greatly…
Thank you, Aniruddha.
You’re welcome! I’m glad you like it.