Encapsulation in Python
OOP Design
Encapsulation
Encapsulation isn't about private keywords—it's about clear boundaries. Use naming conventions, properties, and helper classes to build trustable APIs.
Naming conventions
_single_leading_underscoresignals "internal use."__double_leadingtriggers name mangling—rarely needed.propertyallows validation while exposing attribute-like syntax.
class Account:
def __init__(self):
self._balance = 0.0
@property
def balance(self) -> float:
return self._balance
def deposit(self, amount: float) -> None:
if amount <= 0:
raise ValueError("Deposit must be positive")
self._balance += amount
Property setters
Add a setter to allow controlled writes:
class Account:
def __init__(self, balance: float = 0.0):
self._balance = balance
@property
def balance(self) -> float:
return self._balance
@balance.setter
def balance(self, value: float) -> None:
if value < 0:
raise ValueError("Balance cannot be negative")
self._balance = value
Use @property without a setter for read-only attributes.
Composition > inheritance
Encapsulation thrives when responsibilities are split into collaborating objects instead of huge base classes.