Object-Oriented Programming in Python: Classes and dataclasses
I modeled a small automation domain with Python classes, abstract base classes, and dataclasses for value objects. An explicit object model with clear interfaces made the system easy to extend and unit-test without touching existing code.
Objective & Context
OOP organizes state and behaviour behind interfaces. This lab covers instance vs class attributes, inheritance, polymorphism via abstract base classes, and boilerplate-free value types with @dataclass, applying the open/closed principle to automation components.
Environment & Prerequisites
- Python 3.11 with dataclasses and abc.
- A domain with multiple related entity types.
- pytest for behaviour verification.
classDiagram
class Notifier
class SlackNotifier
class EmailNotifier
Notifier <|-- SlackNotifier
Notifier <|-- EmailNotifier
Step-by-Step Execution
1. Define an interface with abc
from abc import ABC, abstractmethod
class Notifier(ABC):
@abstractmethod
def send(self, msg: str) -> bool: ...
2. A dataclass value object
python -c "from dataclasses import dataclass; exec('@dataclass\nclass Alert:\n ip:str\n sev:int'); print(Alert('1.2.3.4',2))"3. Polymorphic dispatch
python -c "from notify import SlackNotifier; SlackNotifier().send('up')"Alert(ip='1.2.3.4', sev=2)
Validation & Testing
Add a new Notifier subclass without modifying the dispatcher and confirm it works via the shared interface. Pass criteria: subclasses are interchangeable, dataclasses compare by value, and abstract methods enforce the contract.
Advanced: Troubleshooting
- Cannot instantiate ABC: implement all abstract methods in the subclass.
- Mutable dataclass default: use
field(default_factory=list). - Shared class attribute mutated: initialize per-instance state in
__init__.
Key Results
- Modeled the domain behind a single abstract interface.
- Added new behaviour via subclassing with zero changes to callers.
- Eliminated boilerplate with dataclass value objects.
- Verified polymorphism and value equality with unit tests.