Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
What does double underscore prefix do in Python variables?
In Python, a double underscore prefix (__) triggers name mangling, which automatically transforms the attribute name to include the class name. This mechanism prevents naming conflicts in inheritance hierarchies.
What is Name Mangling?
When you prefix a variable with double underscores, Python automatically renames it by adding _ClassName before the original name. This makes the attribute "private" to that specific class.
class Python:
def __init__(self):
self.car = 5 # Normal attribute
self._buzz = 9 # Single underscore (convention only)
self.__fee = 2 # Double underscore (name mangled)
obj = Python()
print(dir(obj))
['_Python__fee', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_buzz', 'car']
Notice that __fee appears as _Python__fee in the output ? This is name mangling in action.
Accessing Private Attributes
From Inside the Class
class Sports:
def __init__(self, players):
self.players = players
def set_names(self, names):
self.__names = names
def get_names(self):
return self.__names
cricket = Sports(12)
cricket.set_names("Sachin Tendulkar")
print(cricket.get_names()) # Works fine
print(cricket.players) # Works fine
Sachin Tendulkar 12
Direct Access (Will Fail)
# This will raise AttributeError print(cricket.__names)
AttributeError: 'Sports' object has no attribute '__names'
Accessing via Mangled Name
You can still access the attribute using the mangled name ?
class TestClass:
def __init__(self):
self.__private_var = "secret"
obj = TestClass()
print(obj._TestClass__private_var) # Access using mangled name
secret
Preventing Inheritance Conflicts
Name mangling prevents subclass attributes from overriding parent class private attributes ?
class Parent:
def __init__(self):
self.__value = "parent"
def get_value(self):
return self.__value
class Child(Parent):
def __init__(self):
super().__init__()
self.__value = "child" # Creates _Child__value, not _Parent__value
def get_child_value(self):
return self.__value
child = Child()
print(child.get_value()) # Returns parent value
print(child.get_child_value()) # Returns child value
parent child
Key Points
- Double underscore prefix applies to both variables and methods
- Name mangling only occurs within class definitions
- It's not true privacy ? you can still access via mangled names
- Used to prevent accidental overriding in inheritance
Comparison
| Prefix | Example | Behavior | Use Case |
|---|---|---|---|
| None | var |
Public access | Normal attributes |
| Single _ | _var |
Convention only | Internal use indicator |
| Double __ | __var |
Name mangled | Avoid inheritance conflicts |
Conclusion
Double underscore prefix triggers name mangling to prevent attribute conflicts in inheritance. While it provides pseudo-privacy, its main purpose is avoiding accidental overrides in subclasses.
