Fundamentals 7 min read

Is Object‑Oriented Programming Unnecessary in Python? A Functional Alternative

The article argues that while object‑oriented programming isn’t inherently flawed, it is often unnecessary in Python, illustrating how the same tasks can be achieved with simple data classes and pure functions, reducing code size and improving clarity.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Is Object‑Oriented Programming Unnecessary in Python? A Functional Alternative

1. No Need for OOP

Many people criticize object‑oriented programming; the author does not see a problem with OOP itself but believes it is often unnecessary in Python.

Example of code that uses OOP without real need:

class ApiClient:
    def __init__(self, root_url: str, session_cls: sessionmaker):
        self.root_url = root_url
        self.session_cls = session_cls

    def construct_url(self, entity: str) -> str:
        return f"{self.root_url}/v1/{entity}"

    def get_items(self, entity: str) -> List[Item]:
        resp = requests.get(self.construct_url(entity))
        resp.raise_for_status()
        return [Item(**n) for n in resp.json()["items"]]

    def save_items(self, entity: str) -> None:
        with scoped_session(self.session_cls) as session:
            session.add(self.get_items(entity))

class ClientA(ApiClient):
    def construct_url(self, entity: str) -> str:
        return f"{self.root_url}/{entity}"

class ClientB(ApiClient):
    def construct_url(self, entity: str) -> str:
        return f"{self.root_url}/a/special/place/{entity}"

client_a = ClientA("https://client-a", session_cls)
client_a.save_items("bars")

The OOP approach binds root_url and a sessionmaker to an object and uses inheritance to vary URL construction.

However, the same functionality can be expressed with plain data structures and functions:

@dataclass
class Client:
    root_url: str
    url_layout: str

client_a = Client(root_url="https://client-a", url_layout="{root_url}/{entity}")
client_b = Client(root_url="https://client-b", url_layout="{root_url}/a/special/place/{entity}")

def construct_url(client: Client, entity: str) -> str:
    return client.url_layout.format(root_url=client.root_url, entity=entity)

def get_items(client: Client, entity: str) -> List[Item]:
    resp = requests.get(construct_url(client, entity))
    resp.raise_for_status()
    return [Item(**n) for n in resp.json()["items"]]

def save_items(client: Client, session_cls, entity: str) -> None:
    with scoped_session(session_cls) as session:
        session.add(get_items(client, entity))

save_items(client_a, session_cls, "bars")

This functional style eliminates the need to pass the Client and session_cls around constantly, reduces code size by about 10 %, and remains easy to understand without OOP.

The author calls this “function‑bag” style: the program consists of typed data and a collection of module‑level functions.

Global configuration can be handled by reusing a config or DB session throughout the application lifecycle (see the linked article).

Interfaces and abstract classes are unnecessary; with type annotations, the function‑bag approach shines.

2. Exceptions

Using @dataclass to record types is fine; Python 3 supports it natively.

Subclassing Exception is acceptable; simple try/except hierarchies are fine as long as they stay simple.

Enums are also suitable for Python.

In rare cases you might create a highly useful type (e.g., pandas.DataFrame or sqlalchemy.Session), but generally avoid over‑engineering.

3. Drawbacks of OOP

OOP encourages mutable state; function‑bag style discourages modifying parameters.

OOP often forces reliance on global variables via self, limiting data sharing between functions.

Mixing data and behavior makes serialization harder, which is important for modern REST APIs.

Deep inheritance hierarchies proliferate and dominate discussions.

Overall, OOP adds little value and can obscure problem solving, making code harder to read and maintain.

Reference: https://leontrolski.github.io/mostly-pointless.html

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

code stylesoftware designfunctional programmingOOPdataclass
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.