Course Content
Python Essentials for AI Engineer
6 sections · 48 lessons
What is Object-Oriented Programming (OOP)?
What you need to know
From loose data to objects
Without OOP, state lives in dicts and logic lives in functions that must be handed that dict every time. Nothing stops someone from changing the dict in a way the functions do not expect. A class keeps them together:
1class SupportBot:2 def __init__(self, model, max_turns=10):3 self.model = model # attributes: the object's data4 self.max_turns = max_turns5 self.history = []67 def ask(self, text): # method: behaviour on that data8 if len(self.history) >= self.max_turns:9 raise RuntimeError("conversation too long")10 self.history.append(text)11 return f"[{self.model}] reply to: {text}"1213bot = SupportBot("chat-small")14print(bot.ask("Where is my refund?")) # [chat-small] reply to: Where is my refund?15print(len(bot.history)) # 1The four pillars, in Python terms
| Pillar | Idea | How Python does it |
|---|---|---|
| Encapsulation | keep state behind methods that protect it | _name convention, @property |
| Inheritance | a child class reuses and specialises a parent | class Child(Parent):, super() |
| Polymorphism | one method call, many behaviours | duck typing, overriding, dunder methods |
| Abstraction | show what, hide how | small public APIs, abc.ABC |
Everything in Python is an object
Numbers, strings, functions and classes are all objects with a type and methods: (255).bit_length() returns 8 and "upi".upper() returns "UPI". So even "non-OOP" Python code uses objects all the time.
When not to use a class
A class with an __init__ and one method is usually just a function in disguise. If there is no state to protect and no family of variants, a function is simpler to read and test.
A real-life example
Why does every scikit-learn model — logistic regression, random forest, SVM — have the same fit(X, y) and predict(X) methods? Because the library is designed around OOP. Each estimator is an object that stores its learned parameters as attributes, and all of them share one interface. So one Pipeline, one cross_val_score and one grid search work with more than a hundred model classes.
You can use the same idea in your own team's code:
1class KeywordClassifier:2 def predict(self, text):3 return "refund" if "refund" in text.lower() else "other"45class AlwaysOther:6 def predict(self, text):7 return "other"89def accuracy(model, data):10 return sum(model.predict(t) == y for t, y in data) / len(data)1112data = [("Refund not received", "refund"), ("Change my address", "other"), ("REFUND pls", "refund")]13for model in (KeywordClassifier(), AlwaysOther()):14 print(type(model).__name__, round(accuracy(model, data), 2))15# KeywordClassifier 1.016# AlwaysOther 0.33When an LLM-based classifier arrives next month, it only needs a predict method to plug into the same accuracy function.
Follow-up questions to expect
- "How is OOP different from procedural programming?" — Procedural code passes data through a sequence of functions; OOP keeps data and the functions that change it together inside objects.
- "Is everything in Python an object?" — Yes. Integers, functions, modules and classes themselves all have a type and attributes.
- "When would you avoid a class?" — When there is no state to manage — a pure transformation like
clean_text(text)is better as a function.