Name Mangling — Core Concepts
What Is Name Mangling?
Name mangling is Python’s mechanism for rewriting attribute names that begin with two (or more) underscores and don’t end with two underscores. Python transforms __attr inside a class MyClass into _MyClass__attr.
This transformation happens at compile time (when the bytecode is generated), not at runtime. It’s completely transparent — you don’t see the change in your source code, but it’s there in the compiled bytecode.
The Rules
Name mangling applies when all three conditions are met:
- The name starts with two or more underscores.
- The name does not end with two or more underscores.
- The name appears inside a class body.
| Name | Mangled? | Result (in class Foo) |
|---|---|---|
__bar | Yes | _Foo__bar |
___bar | Yes | _Foo___bar |
__bar_ | Yes | _Foo__bar_ |
__bar__ | No | Stays __bar__ (dunder method) |
_bar | No | Stays _bar (single underscore convention) |
bar | No | No underscores, no mangling |
The Real Purpose: Preventing Inheritance Collisions
Name mangling isn’t about privacy or security. Its primary purpose is to prevent attribute name collisions between parent and child classes.
The Problem Without Mangling
Imagine a base class with an internal counter:
class Base:
def __init__(self):
self._count = 0 # single underscore — just a convention
def increment(self):
self._count += 1
class Child(Base):
def __init__(self):
super().__init__()
self._count = 100 # Accidentally overwrites Base's _count!
The child class didn’t mean to interfere with the parent’s counter, but both used the name _count.
The Solution With Mangling
class Base:
def __init__(self):
self.__count = 0 # Becomes _Base__count
def increment(self):
self.__count += 1 # Accesses _Base__count
class Child(Base):
def __init__(self):
super().__init__()
self.__count = 100 # Becomes _Child__count — different attribute!
Now Base has _Base__count = 0 and Child has _Child__count = 100. They coexist without interference.
How to Access Mangled Names
You can still access mangled attributes from outside the class — Python isn’t enforcing privacy:
obj = Child()
print(obj._Base__count) # 0
print(obj._Child__count) # 100
This works, but the awkward syntax serves as a strong signal that you’re breaking encapsulation.
Common Misconception
“Double underscores make attributes private.” Python has no access control. Name mangling is about collision avoidance, not privacy. Any code can access _ClassName__attr if it wants to. The single underscore convention (_attr) is the Python community’s way of saying “private” — it’s a social contract, not a technical barrier.
When to Use Name Mangling
Use it when:
- You’re writing a library or framework class that will be extensively subclassed.
- You need an internal attribute that subclasses absolutely must not accidentally override.
- You’re designing a class hierarchy where multiple levels might use similar attribute names.
Don’t use it when:
- You just want a “private” attribute — use single underscore
_attrinstead. - You’re writing application code with simple class hierarchies.
- You want to test internal state easily — mangled names make testing harder.
Gotchas
- Dynamic access fails:
getattr(obj, "__attr")won’t find_Class__attr. You needgetattr(obj, "_Class__attr"). - Pickle and serialization: Some serialization libraries struggle with mangled names because the stored name includes the class name.
- Refactoring hazard: Rename the class, and all mangled names change. External code using
_OldName__attrbreaks silently.
One thing to remember: Name mangling rewrites __attr to _ClassName__attr at compile time. It’s not about privacy — it’s about preventing parent and child classes from accidentally stepping on each other’s internal attributes.
See Also
- Python Abc Abstract Base Classes Why Python's ABC module is like a building inspector who checks your blueprints before construction begins
- Python Class Decorators Understand Class Decorators through an everyday analogy so Python behavior feels intuitive, not random.
- Python Composition Vs Inheritance Understand Composition Vs Inheritance through an everyday analogy so Python behavior feels intuitive, not random.
- Python Cooperative Multiple Inheritance Why Python classes can have multiple parents and still get along — like a kid learning different skills from each family member.
- Python Dataclasses Advanced Understand Dataclasses Advanced through an everyday analogy so Python behavior feels intuitive, not random.