Python Essentials for AI Engineer

Course Content

Python Essentials for AI Engineer

6 sections · 48 lessons

What is Encapsulation?


What you need to know

Underscore conventions

NameMeaningEnforced?
balancepublic—
_balanceinternal; not part of the public APIno, just a convention
__balancename-mangled to _ClassName__balanceonly renamed, still reachable
__init__dunder: special method, not private at all—
Python
class Account:    def __init__(self):        self._balance = 100        self.__pin = "1234"acc = Account()print(acc._balance)             # 100 -> works; the underscore is a polite "please don't"try:    acc.__pinexcept AttributeError as e:    print("AttributeError")     # AttributeErrorprint(acc._Account__pin)        # 1234 -> mangled, not hidden

Name mangling exists so that a subclass defining its own __pin does not overwrite the parent's by accident. It is not security.

@property: validated attributes

Java-style get_x()/set_x() methods are unusual in Python. Start with a plain attribute. When you later need validation, turn it into a property; callers keep writing obj.x, and their code does not change.

Python
class GenerationConfig:    def __init__(self, temperature=0.2):        self.temperature = temperature        # goes through the setter below    @property    def temperature(self):        return self._temperature    @temperature.setter    def temperature(self, value):        if not 0.0 <= value <= 2.0:            raise ValueError(f"temperature must be between 0 and 2, got {value}")        self._temperature = valuecfg = GenerationConfig()cfg.temperature = 0.7print(cfg.temperature)                         # 0.7try:    cfg.temperature = 7except ValueError as e:    print(e)          # temperature must be between 0 and 2, got 7

Without a setter, the property is read-only. For immutable records, @dataclass(frozen=True) blocks all assignments after creation.

A real-life example

A shared GenerationConfig object is passed through an LLM pipeline. A teammate's script sets cfg.temperature = 7 (they meant 0.7). Without validation, the value travels through three services and the provider rejects it with an HTTP 400 in the middle of a batch of 20,000 requests, hours later. With the property above, the mistake raises ValueError on the exact line that made it, before any money is spent.

The same idea protects any invariant: a Budget whose spent can only grow through charge(), or a ChatSession whose history is exposed as a read-only tuple so no caller can delete messages behind its back.

Follow-up questions to expect

  • "Does Python have private variables?" — Not enforced ones. _x is a convention and __x is name-mangled; both are still reachable. Python relies on "we're all consenting adults".
  • "What is name mangling?" — Python renames __x inside class C to _C__x, so subclasses cannot accidentally overwrite it.
  • "Why @property instead of get_x()?" — It keeps the simple obj.x syntax and lets you add validation later without changing any caller.