Inheritance
Inheritance is a way to build a new class on an existing one, so the new class gets every method of the parent and changes only what differs.
Last updated: 13 Oct, 2026 · Python 3.12
Agent frameworks often hand you a base class and ask you to write one method. That is inheritance, built on Classes and Methods.
audi. Python's style guide capitalises class names, so the run below uses Audi; the rest of the code is as on screen.class Car:
def __init__(self, windows, doors, enginetype):
self.windows = windows
self.doors = doors
self.enginetype = enginetype
def drive(self):
print("The Person drives the car")
class Audi(Car):
def __init__(self, windows, doors, enginetype, enableai):
# reuse the parent __init__ for the shared fields, then add the new one
super().__init__(windows, doors, enginetype)
self.enableai = enableai
def selfdriving(self):
print("Audi supports Self driving")
audiQ7 = Audi(5, 5, "diesel", True)
print(audiQ7.windows, audiQ7.enableai)
audiQ7.drive()5 True The Person drives the car
Audi never defines drive or windows; both come from Car, because super().__init__ ran the parent's setup. The model classes below follow the same pattern.
Syntax:
class Child(Parent):
def __init__(self, a, b):
super().__init__(a) # run the parent's __init__ too
self.b = bA base class with one missing method
The base class below works for any model. It knows how to answer a list of texts, but not how to answer one:
class Model:
def ask(self, text):
raise NotImplementedError("a model must say how it answers")
def ask_all(self, texts):
return [self.ask(text) for text in texts]
Model().ask("refund please")Traceback (most recent call last):
File "main.py", line 8, in <module>
Model().ask("refund please")
File "main.py", line 3, in ask
raise NotImplementedError("a model must say how it answers")
NotImplementedError: a model must say how it answersask_all calls self.ask for each text. ask itself only raises NotImplementedError, Python's standard way to say that a subclass must fill this in. Delete that line before you add the next example: an error stops the file where it happens.
Filling in the one method
class KeywordModel(Model):
def ask(self, text):
# a stand-in model: no network, only keyword rules that return JSON text
if "refund" in text.lower() or "charged" in text.lower():
return '{"category": "billing", "priority": 4}'
return '{"category": "other", "priority": 1}'
model = KeywordModel()
print(model.ask("Can I get a refund?"))
print(model.ask_all(["I was charged twice", "Hello"])){"category": "billing", "priority": 4}
['{"category": "billing", "priority": 4}', '{"category": "other", "priority": 1}']class KeywordModel(Model) means KeywordModel inherits from Model. It gets ask_all without writing it, and its own ask replaces the one that raised. When ask_all calls self.ask, self is a KeywordModel, so the new version runs.
This is the pattern behind the stand-in models in the agent framework courses: subclass the framework's model class, write the method that produces an answer, and the framework's code does the rest.
Keeping the parent's __init__ with super()
class Model:
def __init__(self, name):
self.name = name
class KeywordModel(Model):
def __init__(self, keywords):
# super().__init__ runs the parent setup, so self.name is set too
super().__init__(name="keywords")
self.keywords = keywords
model = KeywordModel(["refund", "charged"])
print(model.name, model.keywords)
print(isinstance(model, Model))keywords ['refund', 'charged'] True
A subclass with its own __init__ replaces the parent's, so name would never be set. super().__init__(...) runs the parent's version too. isinstance confirms a KeywordModel counts as a Model, which is what lets framework code accept it.
Multiple inheritance and the method resolution order
D from two base classes B and C and calls it multiple inheritance. The page names the rule Python uses to pick which parent's method runs, the method resolution order (MRO), and reads it with __mro__.class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print("Subclass must implement this method")
class Pet:
def __init__(self, owner):
self.owner = owner
# Dog inherits from both Animal and Pet
class Dog(Animal, Pet):
def __init__(self, name, owner):
Animal.__init__(self, name) # call each parent initialiser by name
Pet.__init__(self, owner)
def speak(self):
return f"{self.name} say woof"
dog = Dog("Buddy", "Krish")
print(dog.speak())
print(f"Owner:{dog.owner}")Buddy say woof Owner:Krish
A class can inherit from more than one parent. When two parents define the same method, Python follows the method resolution order, the base classes left to right, and uses the first one it finds.
class Loggable:
def describe(self):
return "loggable"
class Model:
def describe(self):
return "model"
class LoggingModel(Loggable, Model):
# both parents define describe(); the MRO decides which one wins
passm = LoggingModel()
print(m.describe())
print([c.__name__ for c in LoggingModel.__mro__])loggable ['LoggingModel', 'Loggable', 'Model', 'object']
describe runs Loggable's because Loggable comes first in LoggingModel(Loggable, Model). __mro__ is the exact search order Python follows, ending at object, the class every class inherits from.
Parent vs child class
Model (parent) | KeywordModel (child) | |
|---|---|---|
ask_all | Written here | Inherited |
ask | Raises NotImplementedError | Replaced with a real answer |
isinstance(x, Model) | True | True |
Where inheritance shows up in AI code
- Pydantic models inherit from
BaseModel, as Pydantic models shows. - Custom tools, models and callbacks in agent frameworks subclass a base class the framework provides.
__init__ without super().__init__(...) skips the parent's setup, and the attributes it would have set are missing. Reading one later is an AttributeError.Related
- Previous: dataclasses
- Next: Type hints
- Reference: Inheritance in the Python tutorial
- Remove the
super().__init__line and printmodel.name. - In a new file with the first
Modelclass, the one withask_all, write a second subclass,PoliteModel, whoseaskalways returns"Thank you for your message.", and callask_allon it. - Give KeywordModel's
aska"parcel"branch that returns shipping. - Swap the bases to
LoggingModel(Model, Loggable)and see whichdescribe()runs and how__mro__changes.
Slow is fine. Stopping is the only problem.