Loading lessons...
Encapsulation and Inner Classes
Encapsulation and Inner Classes
Encapsulation hides an object's internal data. Inner classes are classes defined inside other classes.
Private attributes with _
A single underscore is a convention meaning "keep it internal":
class MyClass:
def __init__(self):
self._protected = "don't touch"
Stronger privacy with __
Double underscores trigger name mangling, making the attribute harder to reach from outside:
class MyClass:
def __init__(self):
self.__private = "secret"
obj = MyClass()
print(obj.__private) # AttributeError
It's still reachable as obj._MyClass__private, so it's a warning, not a wall.
Encapsulation via methods
Expose data through methods instead of direct access:
class BankAccount:
def __init__(self, balance):
self.__balance = balance
def get_balance(self):
return self.__balance
def deposit(self, amount):
if amount > 0:
self.__balance += amount
Getters and setters
@property gives a clean, attribute-like interface:
class Person:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
Inner classes
A class can live inside another class:
class Outer:
class Inner:
def method(self):
print("Inner method")
Use the dot chain to reach it:
obj = Outer.Inner()
obj.method() # Inner method
Why inner classes?
They group closely related classes and limit their visibility.
TL;DR
- Single _ is a convention; double __ triggers name mangling.
- Encapsulation exposes data through methods.
- @property creates clean getters/setters.
- Inner classes live inside another class.