Learn

Short lessons with real code you can edit and run on the page.

Inheritance in Python

Lesson 29 Python 3.14 Runs in your browser
In short

Inheritance lets a new class reuse the attributes and methods of an existing class. You name the parent class in parentheses, as in class Dog(Animal):, and the subclass can add methods, override inherited ones or extend them with super().

Key facts

  • class Dog(Animal): makes Dog a subclass of Animal, so a Dog object can use every method Animal defines.
  • A subclass with no __init__ of its own uses the parent's __init__.
  • A method defined in the subclass overrides the parent's method with the same name.
  • super().__init__(name) runs the parent's __init__ from inside the subclass.
  • isinstance(rex, Animal) is True when rex is an instance of any subclass of Animal.

What is inheritance in Python?

Inheritance lets a new class reuse the attributes and methods of an existing class. The new class is called a subclass or child class, and the class it inherits from is its parent class or base class.

Python
class Animal:
    def __init__(self, name):
        self.name = name

    def describe(self):
        print(self.name, "is an animal")

class Dog(Animal):
    def bark(self):
        print(self.name, "says woof")

rex = Dog("Rex")
rex.describe()
rex.bark()
Output
Rex is an animal
Rex says woof

The parent goes in parentheses after the subclass name, so class Dog(Animal): makes Dog a subclass of Animal. Dog defines only bark(), yet rex.describe() works and Dog("Rex") sets the name.

When Python can't find a method or attribute on the object or its own class, it looks in the parent class next. That includes __init__, which is why Dog needs no __init__ of its own.

How do I override a method in Python?

Define a method with the same name in the subclass. Python finds the subclass's version first and runs it instead of the parent's, which is called overriding.

Python
class Animal:
    def speak(self):
        return "..."

class Dog(Animal):
    def speak(self):
        return "Woof"

class Cat(Animal):
    def speak(self):
        return "Meow"

for pet in [Dog(), Cat(), Animal()]:
    print(type(pet).__name__, pet.speak())
Output
Dog Woof
Cat Meow
Animal ...

The loop calls speak() on three objects without checking their types, and each answers with its own class's version. Using one method name across different classes like this is called polymorphism. type(pet).__name__ gives the class name as text.

What does super() do in Python?

super() lets a subclass call the parent class's version of a method. Its most common use is in a subclass's __init__, so the parent's __init__ can set up the object before the subclass adds its own attributes.

Python
class Employee:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary

class Manager(Employee):
    def __init__(self, name, salary, team):
        super().__init__(name, salary)
        self.team = team

boss = Manager("Ada", 90000, ["Grace", "Linus"])
print(boss.name, boss.salary, len(boss.team))
Output
Ada 90000 2

super().__init__(name, salary) runs Employee.__init__ on the new manager, so self.name and self.salary are set exactly as for any employee.

Pass the arguments the parent's __init__ expects, without self, because super() already knows which object it is working on.

Python
class Employee:
    def __init__(self, name):
        self.name = name

    def describe(self):
        return f"{self.name}, employee"

class Manager(Employee):
    def describe(self):
        return super().describe() + " and manager"

print(Employee("Grace").describe())
print(Manager("Ada").describe())
Output
Grace, employee
Ada, employee and manager

super() isn't limited to __init__. The manager's describe() adds " and manager" to the text super().describe() returns, instead of repeating the parent's code.

How do isinstance() and issubclass() work with subclasses?

isinstance() returns True for an object of the class or of any subclass of it. issubclass() asks the same question about two classes, as in issubclass(Dog, Animal).

Python
class Animal:
    pass

class Dog(Animal):
    pass

rex = Dog()
print(isinstance(rex, Dog), isinstance(rex, Animal))
print(type(rex) == Animal)
print(issubclass(Dog, Animal), issubclass(Animal, Dog))
Output
True True
False
True False

A dog is an animal, so both isinstance() checks return True, but type(rex) == Animal is False, because the object's exact type is Dog. Use isinstance() when subclasses should pass the test too.

The data types lesson called bool a subtype, or subclass, of int, so isinstance(True, int) is True.

Animal and Dog contain only pass, the placeholder from the break and continue lesson, because a class body needs at least one statement.

How do I create a custom exception class in Python?

Write a class that inherits from Exception. Its body can be pass alone, because everything an exception needs comes from the parent class.

Python
class InsufficientFundsError(Exception):
    pass

def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError(f"need {amount - balance} more")
    return balance - amount

try:
    withdraw(50, 80)
except InsufficientFundsError as e:
    print("Declined:", e)
Output
Declined: need 30 more

A custom exception lets callers catch this problem and nothing else. PEP 8 asks that exception names end in Error when the exception is an error.

Because the class inherits from Exception, an except Exception clause catches it too, along with the built-in exceptions from the errors and exceptions lesson.

Can a Python class inherit from more than one class?

Yes, and it is called multiple inheritance. List the parent classes in the parentheses, and when two of them define the same method, the one listed first wins.

Python
class Flyer:
    def move(self):
        return "fly"

class Swimmer:
    def move(self):
        return "swim"

class Duck(Flyer, Swimmer):
    pass

print(Duck().move())
print([cls.__name__ for cls in Duck.__mro__])
Output
fly
['Duck', 'Flyer', 'Swimmer', 'object']

Duck lists Flyer first, so move() comes from Flyer. Duck.__mro__ holds the order Python searches for methods and attributes, called the method resolution order or MRO, and the list comprehension collects each class's name.

The MRO ends with object, the built-in class every Python class inherits from. super() follows the MRO of the instance's class, so for a Duck, super() in a Flyer method reaches Swimmer's method next, though Swimmer isn't Flyer's parent.

Most classes need only one parent. Several parents are mainly used for mixins, small add-on classes that each supply a few methods.

What are the types of inheritance in Python?

Tutorials list five types of inheritance, which are single, multiple, multilevel, hierarchical and hybrid. They are shapes a family of classes can take rather than separate features, and all five use the same class Child(Parent): syntax.

Types of inheritance in Python
TypeShapeExample
SingleOne subclass of one parentclass Dog(Animal):
MultipleOne subclass of two or more parentsclass Duck(Flyer, Swimmer):
MultilevelA chain, where a subclass has its own subclassclass Puppy(Dog):, with Dog a subclass of Animal
HierarchicalSeveral subclasses of one parentclass Dog(Animal): and class Cat(Animal):
HybridA mix of these shapesTwo subclasses of Animal, plus a class that inherits from both

Common mistakes with inheritance in Python

These four mistakes with Python inheritance leave a subclass missing attributes or behaving differently than you meant.

  • AttributeError: 'Manager' object has no attribute 'name'. The subclass's own __init__ overrides the parent's, so the parent's setup never ran. Call super().__init__() with the parent's arguments.
  • TypeError: Employee.__init__() takes 2 positional arguments but 3 were given. super().__init__(self, name) sends the object twice. Leave self out of the call.
  • Checking the type with ==. type(rex) == Animal is False for a Dog, so code that tests types this way rejects subclasses. Use isinstance().
  • Inheriting where the is-a test fails. The test asks whether the subclass is a kind of the parent. A car is not an engine, yet a Car that inherits from Engine gets every engine method. Store an Engine object in an attribute instead, which is called composition.

The program below forgets to call super().__init__(). Add super().__init__(name) as the first line of the manager's __init__ and run it again.

Python
class Employee:
    def __init__(self, name):
        self.name = name

class Manager(Employee):
    def __init__(self, name, team):
        self.team = team

boss = Manager("Ada", ["Grace"])
print(boss.name)
Output
Traceback (most recent call last):
  File "main.py", line 10, in <module>
    print(boss.name)
          ^^^^^^^^^
AttributeError: 'Manager' object has no attribute 'name'

Exercise

Change Square.__init__() so it calls super().__init__(side, side), and the program prints 16. The starter stops with an AttributeError, because the rectangle's __init__ never runs and the square has no width.

Python
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

class Square(Rectangle):
    def __init__(self, side):
        self.side = side

print(Square(4).area())
Output
Show the solution
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

class Square(Rectangle):
    def __init__(self, side):
        super().__init__(side, side)

print(Square(4).area())

Quiz

This quiz has 5 questions. Pick an answer to see why it is right or wrong.

  1. 1What does this program print?

    class A:
        def hello(self):
            return "A"
    
    class B(A):
        def hello(self):
            return "B" + super().hello()
    
    print(B().hello())
  2. 2What does this program print?

    class Animal:
        pass
    
    class Dog(Animal):
        pass
    
    d = Dog()
    print(isinstance(d, Animal), type(d) == Animal)
  3. 3Dog inherits from Animal, and only Animal defines __init__(self, name). What happens when you call Dog("Rex")?

  4. 4What does this program print?

    class Flyer:
        def move(self):
            return "fly"
    
    class Swimmer:
        def move(self):
            return "swim"
    
    class Duck(Swimmer, Flyer):
        pass
    
    print(Duck().move())
  5. 5Which line defines Manager as a subclass of Employee?

Frequently asked questions

Is __init__ inherited in Python?
Yes. A subclass that doesn't define __init__ uses its parent's, and one that does define it overrides the parent's version, which then runs only if you call it yourself, usually with super().__init__().
Do I have to call super().__init__() in a subclass?
Only when the subclass defines its own __init__ and still needs the setup the parent's __init__ does. Leaving the call out skips that setup, so reading an attribute it would have set raises AttributeError.
Does every Python class inherit from object?
Yes. In Python 3 every class inherits from the built-in class object, even when its definition lists no parent, so writing class Animal(object) means the same as leaving the parentheses out.
What is polymorphism in Python?
Polymorphism means different classes share a method name, so one call works on any of them. A loop that calls speak() on a Dog and a Cat gets a different answer from each without checking their types.
What is the difference between inheritance and composition in Python?
Inheritance makes a class a kind of another class, as a Dog is an Animal. Composition stores another object in an attribute, as a Car has an Engine, and it is the better fit whenever the is-a test fails.
What is the MRO in Python?
The MRO, or method resolution order, is the order Python searches classes for a method or attribute. The order starts with the class itself, and ClassName.__mro__ shows it. super() follows this order to decide whose version of a method runs next.
What is the difference between a parent class and a child class in Python?
The parent class, also called the base class or superclass, is the class being inherited from. The child class, or subclass, names the parent in its class line and can use everything the parent defines.