Encapsulation Conventions and Name Mangling
15 min · Intermediate
Need help? Ask a tutor on WhatsApp (opens in a new tab)Python has no private keyword. A class marks what is internal by naming rules, and the team follows them: a leading underscore means "internal, please do not touch". Name mangling is a narrow tool for one problem, a subclass reusing a name by accident. It is not a lock.
Public Attributes and Direct Access
Encapsulation is keeping an object's data and the rules for changing it together in one class, so callers use the class's methods instead of editing its internals.
By default, all attributes in Python are public. You can read and modify them directly.
class Device: def __init__(self, model): self.model = model # PublicExample 1 · Public attribute with no guard
class Product: def __init__(self, name, price): self.name = name self.price = price
item = Product("Keyboard", 1200)item.price = -50print(item.name, item.price)Keyboard -50
What this code does
- Nothing checks
price, so a negative value is accepted. - This is the problem encapsulation solves: a rule needs one place to live.
If an attribute has no prefix, it is part of the public interface.
The Single Underscore Convention (_protected)
Protected attribute is a name that starts with one underscore, such as _balance. It tells other developers it is internal. Python does not stop access.
Prefixing an attribute with a single underscore is an explicit warning to other developers: "This is internal implementation detail; do not rely on or touch it directly outside the class."
class ConnectionPool: def __init__(self, max_connections): self._max_connections = max_connections self._active_connections = []
def get_status(self): return f"Active: {len(self._active_connections)}/{self._max_connections}"Example 2 · Underscore marks internal state
class Order: def __init__(self): self._lines = []
def add(self, sku, qty): self._lines.append((sku, qty))
def count(self): return len(self._lines)
order = Order()order.add("A-100", 2)order.add("B-200", 1)print(order.count())print(order._lines)2
[('A-100', 2), ('B-200', 1)]What this code does
- Callers should use
addandcount. - Reading
_linesstill works, because the underscore is a request, not a lock.
Python does not enforce access restrictions on _var at the interpreter level, but linters and IDEs respect it as internal.
Double Underscore Name Mangling (__private)
Name mangling is Python renaming an attribute written as __name inside class Account to _Account__name. It avoids accidental clashes in subclasses and is not privacy.
When you prefix an attribute with two leading underscores (and at most one trailing underscore), Python actively mangles the attribute name by prepending _ClassName.
class BankVault: def __init__(self, code): self.__vault_code = code # Mangled!
vault = BankVault(9944)# print(vault.__vault_code) # Raises AttributeError!print(vault._BankVault__vault_code) # 9944 (mangled name)Example 3 · Mangling keeps parent and child apart
class Base: def __init__(self): self.__token = "base"
class Child(Base): def __init__(self): super().__init__() self.__token = "child"
c = Child()print(sorted(vars(c)))print(c._Base__token, c._Child__token)['_Base__token', '_Child__token'] base child
What this code does
vars(c)lists the real stored names:_Base__tokenand_Child__token.- Two classes used
__token, and neither overwrote the other.
Name mangling is designed to prevent subclasses from accidentally overwriting internal parent attributes, not for security encryption.
Best Practice Guideline
Start with plain public attributes. Use one underscore for internals. Use two underscores only when a subclass could reuse the same name by mistake. Add a property when a rule must be checked.
- Use public names (
attr) for normal attributes that callers are expected to interact with. - Use single underscore (
_attr) for internal helpers and state. This is what 95% of Python codebases use. - Use double underscore (
__attr) only when building complex inheritance hierarchies where name collisions with subclasses must be strictly avoided.
Next step
Check your understanding
12 quick questions