Python Classes
Bundle data and behaviour with classes, methods, and inheritance.
Why it matters: Retrievers, tokenizers, and model clients are classes you create once and call many times.
Basics
Create a Class
A class is a blueprint. An object is one instance built from it.
__init__ runs when you create the object. self is the instance.
Put expensive setup in __init__ once. Reuse it in methods.
Tiny example
Store a model name on self, then print it.
class Client:
def __init__(self, model):
self.model = model
print(Client("mini").model)Basics
Methods and __call__
Methods are functions that take self first.
__repr__ controls how the object looks when printed. Add one for easier debugging.
__call__ lets you write obj(x) like a function. That is why model code often looks like model(inputs).
Tiny example
Make an instance callable with __call__.
class Doubler:
def __call__(self, x):
return x * 2
print(Doubler()(5))Basics
Inheritance
A subclass reuses a parent class: class Child(Base):.
Call super().__init__(...) so the parent still sets up its state.
In your own code, prefer composition (hold other objects) over deep inheritance trees.
Tiny example
Call super().__init__ from a subclass.
class Base:
def __init__(self, name):
self.name = name
class Child(Base):
def __init__(self, name):
super().__init__(name)
print(Child("rag").name)Then AI / ML
AI / ML examples
Same idea, used in real AI work. Press Try in lab to run it.
AI / ML example
AI / ML: a tiny retriever
Build the index once in __init__, then search many times.
In AI / ML: Retrievers and embedders load indexes or models in __init__.
example.py
Python
class KeywordRetriever:
def __init__(self, documents):
self.documents = documents
def search(self, query):
q = query.lower()
return [d for d in self.documents if q in d.lower()]
r = KeywordRetriever(["python ml", "kubernetes", "python llm"])
print(r.search("python"))AI / ML example 2
AI / ML: callable scaler
An object that behaves like a function.
In AI / ML: PyTorch modules are called as model(x) because of __call__.
example.py
Python
class Scaler:
def __init__(self, factor):
self.factor = factor
def __call__(self, values):
return [v * self.factor for v in values]
scale = Scaler(0.5)
print(scale([1.0, 2.0, 3.0]))Takeaways
- 1__init__ sets up state once; methods reuse it.
- 2__call__ makes an object work like a function.
- 3Use inheritance carefully; prefer composition in your own code.