Python’s Name Mangling Fully Explained: Is it Worth Using?
DOES IT REALLY MAKE YOUR CO-WORKERS HATE YOU?
The effectiveness and use of private or protected attributes have always been subject to debate by some programmers, especially for new learners. Programming Languages such as Java apply strict restrictions on private attributes making them only accessible within the class defining them. In Python private or protected attributes are not natively supported, instead, it uses a mechanism called “Name Mangling” to indicate if an attribute is private. An attribute is indicated as private if has two leading underscores and is protected if starts with one underscore. Name Mangling is a process where Python adds an underscore followed by the class name to the name of the private indicated variable. This helps to counter naming conflicts among other classes including subclasses. Unlike Java, In Python there are no such strict access restrictions applied to the private/protected indicated attributes although manually accessing them is strongly discouraged. This has caused doubt among Python developers about its practical worthiness. In this article, I’ll be discussing Python’s Name Mangling Mechanism, its functions, pros and cons, and usefulness.
In Python, natively private/protected attributes are not supported. Declaring an attribute, such as a variable or method, with a single or two leading underscores acts as an agreement or a kind of contract among Python developers to signify that this variable should only be accessed and modified inside of the class defining it. While it is possible to modify them, it is strongly discouraged by the community from doing so, since it can reduce the readability of the code. I will explore different ways of accessing the variables after outlining how each attribute type is handled inside a class.
How do names get mangled?
Only attributes defined with two leading underscores in their name will be name mangled, For better understanding, take a look at the example below:
⚠️ Pay close attention to the images before moving on so fast. Now pay attention to the output of the dir() function:
Did you notice what happened? As you can see in the last row __privateVar
has become _MyClass__privateVar
but why? Duo to having two leading underscores.
What’s the purpose of private attributes and Name Mangling?
1- Prevent Conflicts in Inheritance
It helps avoid a private attribute of a subclass overwriting another private attribute with the same name in the parent class. Take a look at this example:
What do you think would be the output?
┌──(nightfury㉿kali)-[~/leaveSomeClapsBaby]
└─$ python3 main.py
I'll be name mangled.
Hahahaa what color is your buggati?
That’s because each private variable will be mangled according to the class name defining it, so there won’t be any name conflicts or overwriting. In the example above if you add the following lines:
The output will be:
┌──(nightfury㉿kali)-[~/leaveSomeClapsBaby]
└─$ python3 main.py
I'll be name mangled.
Hahahaa what color is your buggati?
['_MyClass__privateVar'] ['_SubClass__privateVar']
As you just saw each private variable is mangled depending on the name of the class defining it.
2- Encapsulation
Another use of private attributes is to encapsulate data within the class itself and restrict any access from outside to the private variables. But in Python, only direct access to private attributes is restricted, you can still modify any private variable indirectly, In the next section I have explained how to access them.
How To Access The Private Attributes?
• Private Instance Attributes
what do you think would be the output? Incorrect!, you will be thrown the attribute error below:
┌──(nightfury㉿kali)-[~/leaveSomeClapsBaby]
└─$ python3 main.py
Traceback (most recent call last):
File "/home/leaveSomeClapsBaby/main.py", line 6, in <module>
print( obj.__private_var )
^^^^^^^^^^^^^^^^^
AttributeError: 'MyClass' object has no attribute '__private_var'
But does it mean accessing a private variable is restricted in Python?! how good I thought otherwise! Oh wait, It’s Python, we’re always wrong. To access a private attribute you must use the mangled name as I did in the example below:
class MyClass:
def __init__(self):
self.__private_var = "I'm a private variable."
obj = MyClass()
print( obj._MyClass__private_var )
So we conclude that leading double underscore will not make an attribute fully private in Python, it will just make it harder to access and acts as a “Don’t touch me” for the attribute. But you can still touch if you are a horrible person🥲.
• Protected Instance Members
Protected attributes are one level below the private attributes, you can access them directly without any error but it is considered a bad practice.
• Public Instance Members
Public instance variables and methods are members of a class that are declared without any name mangling and can be directly accessed and modified from outside of the class(instances of the class).
In the image above, you could see that public members are directly accessed by the created instance of the class. public members within a class accessible from both outside and inside of a class.
Conclusion
Name mangling in Python, although unconventional, has its benefits in certain cases, particularly in inheritance. It helps prevent naming conflicts and enhances code organization. However, it can impact code readability. Alternatively, using a single underscore convention (protected) can indicate that an attribute should not be accessed or modified externally. The choice between name mangling and the underscore convention depends on code requirements and communication practices.