1

Introduction

Abstract base classes (ABCs) are used to create classes which are not intended to be instantiated directly, because there is no functionality, only a "template" of what attributes and methods are available. Instead, you create a child class that inherits from the ABC, implement stuff in the child class, and inherit from that. (The StackOverflow abstract-class tag defines them as follows: "Abstract classes are classes which cannot be instantiated. They exist to provide common functionality and interface specifications to several concrete classes.")

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def dream(self):
        pass

We cannot create an instance of Animal directly:

>>> Animal()
TypeError: Can't instantiate abstract class Animal with abstract methods dream

But we can make a subclass which implements dream, and instantiate that:

class Human(Animal):
    def dream(self):
        return "Electric sheep"
Human()

Question

Note that my ABC (Animal) both inherits from the ABC class and defines the dream method as being an abstractmethod. I don't understand why both are necessary.

Details

If I hadn't made the dream method an abstractmethod, then my ABC doesn't actually function as an ABC, because you can instantiate it, even though I was expecting it to complain to me about instantiating ABC:

class Animal(ABC):
    def dream(self):
        pass
barbapapa = Animal()  # Not a specific subclass of Animal. Still works.
barbapapa.dream()

Had I made dream an abstractmethod, but made my Animal class not inherit from ABC, I would still be able to instantiate it:

class Animal(object):
    @abstractmethod
    def dream(self):
        pass
barbapapa = Animal()  # Not a specific subclass of Animal. Still works.
barbapapa.dream()

And this works too! The abstractmethod decoration doesn't seem to do anything without inheriting from ABC.

I understand that a class inheriting from ABC shouldn't mean that you can't create instances of that class. (After all, the classes inheriting from my Animal class should be able to be instantiated, even though those classes indirectly inherit from ABC as well.)

But then why is inheriting from ABC necessary at all? Why not just made it so that you cannot instantiate any class that has abstractmethods (or properties, or whatnot)?

acdr
  • 4,538
  • 2
  • 19
  • 45
  • TL;DR: abstract classes aren't a thing baked into the core syntax, like e.g. Java does. The core Python mechanics are pretty flexible and generic. To emulate abstract class behaviour at all, you need to "add" it through the `ABC` metaclass, and then mark all actual abstract methods as such with the decorator. – deceze Feb 17 '20 at 09:58

0 Answers0