Encapsulation bundles data with the methods that operate on it, and restricts direct access to internal state so invariants stay safe.
Python does not have hard private fields like some languages. It uses conventions:
public: normal names_internal: "protected by convention" (internal use)__mangled: name-mangled to_Class__attrto avoid subclass clashes (not true security)
Properties (@property) expose controlled getters/setters.
class BankAccount:
def __init__(self, balance: float):
self._balance = balance
@property
def balance(self) -> float:
return self._balance
def deposit(self, amount: float) -> None:
if amount <= 0:
raise ValueError("amount must be positive")
self._balance += amount
acct = BankAccount(100)
acct.deposit(50)
print(acct.balance)
# acct.balance = 0 # AttributeError if only getter definedInterview tip: Emphasize convention + API design over "Python has private keywords." Encapsulation is about protecting invariants, not hiding bytes from determined users.