Chapter 20: From Scripts to Systems with Python OOP - Part 1

Why OOP solves the mess of sprawling logic, especially in infrastructure where devices, connections, and services have distinct identities and behaviors.

In case you're trying to read this through your email, be warned: This post is large and may get clipped by services like Gmail and others.

This isn't just an article or a typical post: it is a Python crash course delivered to your inbox. However, since services like Gmail often clip larger emails, I strongly recommend opening it in your browser instead.

1. Why Object-Oriented Programming Matters in Network Engineering

As network engineers, we often think in terms of devices, links, interfaces, VRFs, tunnels, and protocols, all of which are entities with properties and behaviors. A router has interfaces. Each interface has a name, a speed, and an operational state. That router may also run BGP and maintain neighbor relationships. The network itself can be thought of as a system of interacting components.

This mindset of organizing systems by their nature and function is precisely what object-oriented programming (OOP) is about.

In most network automation tasks, engineers begin with procedural scripts that sequentially collect data from devices, analyze it, and produce results. These scripts work well in small, focused scenarios. But as systems grow with more device types, more vendors, more features, and more logic, things get messy. Variables multiply, functions become bloated, and shared logic gets copied and pasted across scripts. Bugs creep in, and complexity explodes.

Eventually, procedural scripts reach a tipping point where they become hard to maintain or extend. That’s when the discipline of software engineering becomes essential, and that’s where OOP enters the scene.

OOP is About Modeling, And Networks Are Already Models

In network engineering, Object-Oriented Programming helps you design systems that reflect the real-world structure of your network. In OOP, you define classes to represent objects (like routers or links) and encapsulate their behavior with methods. These objects can carry state (e.g., the hostname, the platform, the IP address), and perform actions (e.g., check reachability, generate configuration, validate interface health).

By doing this, you make your code more than just a series of instructions: you create reusable building blocks that can evolve and scale with the complexity of your infrastructure.

A Simple Comparison: Procedural vs OOP

Here’s a good example: imagine you want to validate the health of your core routers and edge routers, each with different vendors, interface naming conventions, and configuration rules.

In a procedural script, you might do something like:

if device["vendor"] == "Cisco":
    send_command("show ip interface brief")
elif device["vendor"] == "Juniper":
    send_command("show interfaces terse")

As your device list grows, this quickly becomes brittle. Now consider the same in an OOP style:

device = CiscoRouter(hostname="core1", ip="10.0.0.1")
device.check_interface_status()

Here, the behavior of the device is baked into its class. You don’t have to care how it works; you trust that the object knows how to act like a Cisco router. And if tomorrow you need to support another vendor? You subclass it. No need to edit all your logic. That’s polymorphism, and it’s one of the core strengths of OOP.

Object Reuse > Copy-Paste

In traditional scripting, you often find yourself copying logic around to handle similar cases with slight variations. This leads to fragile code that's hard to refactor.

In OOP, you write your logic once — inside a class — and reuse it across many instances. The behavior is centralized, tested, and abstracted from the rest of the system. If you need to change how BGP reachability is checked for all routers, you update one method in one class, and the change propagates across all devices that inherit from it.

That’s not just elegant. It’s maintainable and scalable.

From Toolmaker to System Designer

OOP encourages you to move from a toolmaking mindset ("let me write a script that works for today") to a system designer mindset ("let me build components I can reuse tomorrow and next year").

This shift is crucial in modern NetDevOps environments where automation is no longer a nice-to-have but the fabric that binds networks together. Whether you're writing inventory managers, change validators, observability pipelines, or config deployers, OOP helps you structure complexity, and that’s what software is all about.

In this edition, we’ll demystify the core building blocks of object-oriented programming, and show how they map naturally to the world you already know: routers, switches, links, and protocols.

Subscribe to keep reading

This content is free, but you must be subscribed to The Routing Intent by Leonardo Furtado to continue reading.

Already a subscriber?Sign in.Not now