Python 3 Deep Dive Part 4 Oop Work

Python 3 Deep Dive Part 4: Object-Oriented Programming (OOP)

Welcome to the fourth installment of our Python 3 Deep Dive series, where we explore the depths of the Python programming language. In this article, we'll dive into the world of Object-Oriented Programming (OOP) in Python 3. OOP is a fundamental concept in programming that allows you to create reusable code, model real-world objects, and write more maintainable and efficient software.

Subtitle: Beyond class and self – Metaclasses, Descriptors, Protocols, and Internals


Chapter 2 — Encapsulation and Properties

Lina wanted to prevent negative years and ensure a title can't be empty. She added validation and a read-only identifier using properties.

import uuid
class Book:
    def __init__(self, title, author, year):
        self._id = uuid.uuid4()
        self.title = title
        self.author = author
        self.year = year
        self._checked_out = False
@property
    def id(self):
        return self._id
@property
    def checked_out(self):
        return self._checked_out
def check_out(self):
        if self._checked_out:
            raise RuntimeError("Already checked out")
        self._checked_out = True
def return_book(self):
        self._checked_out = False
@property
    def year(self):
        return self._year
@year.setter
    def year(self, value):
        if not isinstance(value, int) or value < 0:
            raise ValueError("year must be a non-negative int")
        self._year = value
@property
    def title(self):
        return self._title
@title.setter
    def title(self, value):
        if not value:
            raise ValueError("title cannot be empty")
        self._title = value

Encapsulation gave Lina control: internal state guarded, a clean public API exposed.

Python 3 Deep Dive: Part 4 - Advanced Object-Oriented Programming

The Property Pattern

Pythonic encapsulation is achieved via @property. It allows you to add logic to attribute access without changing the API (i.e., users still type obj.x, but code runs obj.x()). python 3 deep dive part 4 oop

class Celsius:
    def __init__(self, temp=0):
        self._temp = temp
@property
    def temp(self):
        print("Getting value")
        return self._temp
@temp.setter
    def temp(self, value):
        if value < -273.15:
            raise ValueError("Temperature below absolute zero!")
        print("Setting value")
        self._temp = value

3. Container Emulation

Make your objects act like lists or dictionaries.

  • __len__(self): Called by len(obj).
  • __getitem__(self, key): Enables indexing obj[key] and iteration.
  • __setitem__(self, key, value): Enables assignment obj[key] = value.
  • __contains__(self, item): Enables in operator (item in obj).

6. Protocols – structural duck typing (Python 3.8+)

Protocols (from typing) define interfaces via structural subtyping without inheritance.

from typing import Protocol

class Drawable(Protocol): def draw(self) -> None: ... Python 3 Deep Dive Part 4: Object-Oriented Programming

class Triangle: def draw(self) -> None: print("Triangle")

def render(obj: Drawable) -> None: obj.draw()

render(Triangle()) # OK – Triangle implements the protocol Chapter 2 — Encapsulation and Properties Lina wanted

Contrast with ABC: no explicit inheritance, just "looks like a duck".