@Oddthinking's answer is not wrong, but I think it misses the real, practical reason Python has ABCs in a world of duck-typing.

Abstract methods are neat, but in my opinion they don't really fill any use-cases not already covered by duck typing. Abstract base classes' real power lies in the way they allow you to customise the behaviour of isinstance and issubclass. (__subclasshook__ is basically a friendlier API on top of Python's __instancecheck__ and __subclasscheck__ hooks.) Adapting built-in constructs to work on custom types is very much part of Python's philosophy.

Python's source code is exemplary. Here is how collections.Container is defined in the standard library (at time of writing):

class Container(metaclass=ABCMeta):
    __slots__ = ()

    @abstractmethod
    def __contains__(self, x):
        return False

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Container:
            if any("__contains__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

This definition of __subclasshook__ says that any class with a __contains__ attribute is considered to be a subclass of Container, even if it doesn't subclass it directly. So I can write this:

class ContainAllTheThings(object):
    def __contains__(self, item):
        return True

>>> issubclass(ContainAllTheThings, collections.Container)
True
>>> isinstance(ContainAllTheThings(), collections.Container)
True

In other words, if you implement the right interface, you're a subclass! ABCs provide a formal way to define interfaces in Python, while staying true to the spirit of duck-typing. Besides, this works in a way that honours the Open-Closed Principle.

Python's object model looks superficially similar to that of a more "traditional" OO system (by which I mean Java*) - we got yer classes, yer objects, yer methods - but when you scratch the surface you'll find something far richer and more flexible. Likewise, Python's notion of abstract base classes may be recognisable to a Java developer, but in practice they are intended for a very different purpose.

I sometimes find myself writing polymorphic functions that can act on a single item or a collection of items, and I find isinstance(x, collections.Iterable) to be much more readable than hasattr(x, '__iter__') or an equivalent try...except block. (If you didn't know Python, which of those three would make the intention of the code clearest?)

That said, I find that I rarely need to write my own ABC and I typically discover the need for one through refactoring. If I see a polymorphic function making a lot of attribute checks, or lots of functions making the same attribute checks, that smell suggests the existence of an ABC waiting to be extracted.

*without getting into the debate over whether Java is a "traditional" OO system...


Addendum: Even though an abstract base class can override the behaviour of isinstance and issubclass, it still doesn't enter the MRO of the virtual subclass. This is a potential pitfall for clients: not every object for which isinstance(x, MyABC) == True has the methods defined on MyABC.

class MyABC(metaclass=abc.ABCMeta):
    def abc_method(self):
        pass
    @classmethod
    def __subclasshook__(cls, C):
        return True

class C(object):
    pass

# typical client code
c = C()
if isinstance(c, MyABC):  # will be true
    c.abc_method()  # raises AttributeError

Unfortunately this one of those "just don't do that" traps (of which Python has relatively few!): avoid defining ABCs with both a __subclasshook__ and non-abstract methods. Moreover, you should make your definition of __subclasshook__ consistent with the set of abstract methods your ABC defines.

Answer from Benjamin Hodgson on Stack Overflow
🌐
W3Schools
w3schools.com › python › ref_module_abc.asp
Python abc Module
Python Examples Python Compiler Python Exercises Python Quiz Python Challenges Python Server Python Syllabus Python Study Plan Python Interview Q&A Python Bootcamp Python Certificate Python Training · ❮ Standard Library Modules · Define an abstract base class and implement it: from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self): pass class Square(Shape): def __init__(self, s): self.s = s def area(self): return self.s * self.s sq = Square(3) print(isinstance(sq, Shape)) print(sq.area()) Try it Yourself » ·
🌐
Python
docs.python.org › 3 › library › abc.html
abc — Abstract Base Classes
In addition, the collections.abc ... for example, if it is hashable or if it is a mapping. This module provides the metaclass ABCMeta for defining ABCs and a helper class ABC to alternatively define ABCs through inheritance: ... A helper class that has ABCMeta as its metaclass. With this class, an abstract base class can ...
Discussions

Provide a canonical way to declare an abstract class variable - Ideas - Discussions on Python.org
There’s a recent help post of Abstract variables in abc that asks about how an “abstract variable” can be declared such that it is required for a subclass to override the variable, to which @drmason13 replied: Although this approach of abusing an abstract property as an abstract variable ... More on discuss.python.org
🌐 discuss.python.org
10
October 28, 2024
Why use Abstract Base Classes in Python? - Stack Overflow
Yes, I think Set is a better example ... and the Python manual. 2010-08-28T16:12:05.627Z+00:00 ... Any chance of rewriting the answer with Set as the example instead of print? Set makes a lot of sense, @Oddthinking. 2014-02-06T22:58:12.39Z+00:00 ... I think this article explains it very well: dbader.org/blog/abstract-base-classes-in-python ... More on stackoverflow.com
🌐 stackoverflow.com
Django with Abstract Base Classes & Composition
I’m following this Python tutorial from ArjanCodes that talks about composition over inheritance and I wonder how to implement it in Django. I would like to implement the example used (see code below) and I wonder how to implement it in Django. I’m thinking in applying the SOLID principles ... More on forum.djangoproject.com
🌐 forum.djangoproject.com
0
0
December 3, 2022
Adding an Abstract Base Class for Immutable types - Ideas - Discussions on Python.org
Suppose I want to have some of my classes be immutable, there is no simple way to do this in python. I can perhaps do something like this: class MyImmutable: def __setattr__(self, key, value): raise TypeError or perhaps I can inherit from an immutable type like so class MyImmutable(namedtu... More on discuss.python.org
🌐 discuss.python.org
1
May 3, 2020
🌐
DataCamp
datacamp.com › tutorial › python-abstract-classes
Python Abstract Classes: A Comprehensive Guide with Examples | DataCamp
January 22, 2025 - Learn about Python abstract classes, their purpose, and how to use the `abc` module to enforce consistent interfaces. Includes practical examples and best practices for effective implementation.
🌐
Python.org
discuss.python.org › ideas
Provide a canonical way to declare an abstract class variable - Ideas - Discussions on Python.org
October 28, 2024 - There’s a recent help post of Abstract variables in abc that asks about how an “abstract variable” can be declared such that it is required for a subclass to override the variable, to which @drmason13 replied: Although this approach of abusing an abstract property as an abstract variable ...
🌐
dbader.org
dbader.org › blog › abstract-base-classes-in-python
Abstract Base Classes in Python – dbader.org
October 21, 2013 - To make this relationship explicit, the concrete implementations all subclass BaseService. To make this code as maintainable and programmer-friendly as possible we wanted to make sure that: ... forgetting to implement interface methods in one of the subclasses raises an error as early as possible. Now why would you want to use Python’s abc module to solve this problem? The above design is pretty common in more complex systems. To enforce that a derived class implements a number of methods from the base class, something like this Python idiom is typically used:
Top answer
1 of 6
351

@Oddthinking's answer is not wrong, but I think it misses the real, practical reason Python has ABCs in a world of duck-typing.

Abstract methods are neat, but in my opinion they don't really fill any use-cases not already covered by duck typing. Abstract base classes' real power lies in the way they allow you to customise the behaviour of isinstance and issubclass. (__subclasshook__ is basically a friendlier API on top of Python's __instancecheck__ and __subclasscheck__ hooks.) Adapting built-in constructs to work on custom types is very much part of Python's philosophy.

Python's source code is exemplary. Here is how collections.Container is defined in the standard library (at time of writing):

class Container(metaclass=ABCMeta):
    __slots__ = ()

    @abstractmethod
    def __contains__(self, x):
        return False

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Container:
            if any("__contains__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

This definition of __subclasshook__ says that any class with a __contains__ attribute is considered to be a subclass of Container, even if it doesn't subclass it directly. So I can write this:

class ContainAllTheThings(object):
    def __contains__(self, item):
        return True

>>> issubclass(ContainAllTheThings, collections.Container)
True
>>> isinstance(ContainAllTheThings(), collections.Container)
True

In other words, if you implement the right interface, you're a subclass! ABCs provide a formal way to define interfaces in Python, while staying true to the spirit of duck-typing. Besides, this works in a way that honours the Open-Closed Principle.

Python's object model looks superficially similar to that of a more "traditional" OO system (by which I mean Java*) - we got yer classes, yer objects, yer methods - but when you scratch the surface you'll find something far richer and more flexible. Likewise, Python's notion of abstract base classes may be recognisable to a Java developer, but in practice they are intended for a very different purpose.

I sometimes find myself writing polymorphic functions that can act on a single item or a collection of items, and I find isinstance(x, collections.Iterable) to be much more readable than hasattr(x, '__iter__') or an equivalent try...except block. (If you didn't know Python, which of those three would make the intention of the code clearest?)

That said, I find that I rarely need to write my own ABC and I typically discover the need for one through refactoring. If I see a polymorphic function making a lot of attribute checks, or lots of functions making the same attribute checks, that smell suggests the existence of an ABC waiting to be extracted.

*without getting into the debate over whether Java is a "traditional" OO system...


Addendum: Even though an abstract base class can override the behaviour of isinstance and issubclass, it still doesn't enter the MRO of the virtual subclass. This is a potential pitfall for clients: not every object for which isinstance(x, MyABC) == True has the methods defined on MyABC.

class MyABC(metaclass=abc.ABCMeta):
    def abc_method(self):
        pass
    @classmethod
    def __subclasshook__(cls, C):
        return True

class C(object):
    pass

# typical client code
c = C()
if isinstance(c, MyABC):  # will be true
    c.abc_method()  # raises AttributeError

Unfortunately this one of those "just don't do that" traps (of which Python has relatively few!): avoid defining ABCs with both a __subclasshook__ and non-abstract methods. Moreover, you should make your definition of __subclasshook__ consistent with the set of abstract methods your ABC defines.

2 of 6
214

Short version

ABCs offer a higher level of semantic contract between clients and the implemented classes.

Long version

There is a contract between a class and its callers. The class promises to do certain things and have certain properties.

There are different levels to the contract.

At a very low level, the contract might include the name of a method or its number of parameters.

In a staticly-typed language, that contract would actually be enforced by the compiler. In Python, you can use EAFP or type introspection to confirm that the unknown object meets this expected contract.

But there are also higher-level, semantic promises in the contract.

For example, if there is a __str__() method, it is expected to return a string representation of the object. It could delete all contents of the object, commit the transaction and spit a blank page out of the printer... but there is a common understanding of what it should do, described in the Python manual.

That's a special case, where the semantic contract is described in the manual. What should the print() method do? Should it write the object to a printer or a line to the screen, or something else? It depends - you need to read the comments to understand the full contract here. A piece of client code that simply checks that the print() method exists has confirmed part of the contract - that a method call can be made, but not that there is agreement on the higher level semantics of the call.

Defining an Abstract Base Class (ABC) is a way of producing a contract between the class implementers and the callers. It isn't just a list of method names, but a shared understanding of what those methods should do. If you inherit from this ABC, you are promising to follow all the rules described in the comments, including the semantics of the print() method.

Python's duck-typing has many advantages in flexibility over static-typing, but it doesn't solve all the problems. ABCs offer an intermediate solution between the free-form of Python and the bondage-and-discipline of a staticly-typed language.

🌐
Medium
medium.com › @prashampahadiya9228 › abstract-classes-and-abstract-methods-in-python-e632ea34bc79
Abstract Classes and Abstract Methods in Python | by Prasham Pahadiya | Medium
May 31, 2024 - It can include one or more abstract methods. In Python, abstract classes are created using the `abc` module, specifically the `ABC` class. Abstract Methods An abstract method is a method that is declared in an abstract class but does not have an implementation.
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › python › abstract-classes-in-python
Abstract Classes in Python - GeeksforGeeks
Python provides the abc module to define ABCs and enforce the implementation of abstract methods in subclasses. Example: This example shows an abstract class Animal with an abstract method sound() and a concrete subclass Dog that implements it.
Published   September 3, 2025
🌐
Earthly
earthly.dev › blog › abstract-base-classes-python
Abstract Base Classes in Python - Earthly Blog
July 19, 2023 - Learn how to create Abstract Base Classes (ABCs) in Python to enforce the implementation of certain methods or attributes in subclasses. ABCs promo...
🌐
Tutorialspoint
tutorialspoint.com › python › python_abstract_base_classes.htm
Python - Abstract Base Classes
When a class inherits from an Abstract Base Class (ABC) it must implement all abstract methods. If it doesn't then Python will raise a TypeError. Here is the example of enforcing implementation of the Abstract Base Class in Python −
🌐
Django Forum
forum.djangoproject.com › using django › getting started
Django with Abstract Base Classes & Composition - Getting Started - Django Forum
I’m following this Python tutorial from ArjanCodes that talks about composition over inheritance and I wonder how to implement it in Django. I would like to implement the example used (see code below) and …
Published   December 3, 2022
🌐
The Teclado Blog
blog.teclado.com › python-abc-abstract-base-classes
How to Write Cleaner Python Code Using Abstract Classes
October 26, 2022 - We use @abstractmethod to define a method in the abstract base class and combination of @property and @abstractmethod in order to define an abstract property. I hope you learnt something new today! If you're looking to upgrade your Python skills even further, check out our Complete Python Course.
🌐
GitHub
gist.github.com › pknowledge › 8b9a13f238362d34596b79457af37b55
Python Abstract Classes Example · GitHub
Python Abstract Classes Example · Raw · Python_Abstract_Classes_example.py · This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
🌐
CodeSignal
codesignal.com › learn › courses › revisiting-oop-concepts-in-python › lessons › understanding-abstract-classes-and-abstract-methods-in-python
Understanding Abstract Classes and Abstract Methods in ...
These classes serve as blueprints ... the same protocol, making our code more predictable and robust. ... In this snippet, Animal is an abstract class with an abstract method sound....
🌐
GitConnected
levelup.gitconnected.com › exploring-pythons-abstract-base-classes-abc-patterns-and-use-cases-7489bba66a7e
Exploring Python’s Abstract Base Classes (ABC): Patterns and Use Cases | by Aman Kardam (PhD) | Level Up Coding
August 13, 2025 - Abstract Base Classes make it easy to set up common patterns for classes, ensuring that any class that inherits from an ABC has the required methods and properties. In this guide, I’ll share what I’ve learned about Python’s ABCs, why they’re valuable, and some practical examples where ...
🌐
Python.org
discuss.python.org › ideas
Adding an Abstract Base Class for Immutable types - Ideas - Discussions on Python.org
May 3, 2020 - Suppose I want to have some of my classes be immutable, there is no simple way to do this in python. I can perhaps do something like this: class MyImmutable: def __setattr__(self, key, value): raise TypeError or perhaps I can inherit from an immutable type like so class MyImmutable(namedtuple('Immutable', 'foo bar')): def __setitem__(self, item, value): raise TypeError ... but I would have to do this for every immutable class, which becomes complicated.
🌐
Python
peps.python.org › pep-3119
PEP 3119 – Introducing Abstract Base Classes | peps.python.org
MyABC -> MyClass (using regular subclassing) MyClass -> AnotherClass (using registration) AnotherClass -> basestring (using registration) basestring -> str (using regular subclassing) The abc module also defines a new decorator, @abstractmethod, to be used to declare abstract methods. A class containing at least one method declared with this decorator that hasn’t been overridden yet cannot be instantiated. Such methods may be called from the overriding method in the subclass (using super or direct invocation). For example:
🌐
Real Python
realpython.com › ref › glossary › abstract-base-class
abstract base class (ABC) | Python Glossary – Real Python
This is useful for ensuring that derived classes implement particular methods from the base class, providing a consistent interface for different parts of your program. To define an abstract base class, you inherit from abc.ABC and use the @abstractmethod decorator to mark methods that must be implemented by subclasses.
🌐
Python
docs.python.org › 3 › library › collections.abc.html
collections.abc — Abstract Base Classes for Containers
OrderedSet recipe for an example built on MutableSet. For more about ABCs, see the abc module and PEP 3119. collections.abc — Abstract Base Classes for Containers
Top answer
1 of 1
1

There are generally many good ways to implement this. However, everyone have their own preferences, so mostly which of the following you use is up to you. Here's the three approaches:

  1. Do it the way you are currently implementing it. For a basic structure, it'll be something similar to this:
from abc import ABCMeta

class Abstract(metaclass=ABCMeta):
    def write(self):
        raise NotImplementedError()

class Mixin():
    def meth1(self, *args, **kwargs):
        """ do something here"""

class ActualUsefulImplementedClass(Abstract, Mixin):
    """ write your methods here. You will have access to all the helper methods of the mix-in class."""
  1. Implementing the methods as functions (presumably in another file in the same directory as the current file) and call them from inside the class will also be OK:
from abc import ABCMeta
from helpers import func1, func2, func3, ...

class Abstract(metaclass=ABCMeta):
    def write(self):
        raise NotImplementedError()

class ActualUsefulImplementedClass(Abstract, Mixin):
    """ write your methods here. Access the helper functions imported above directly in your methods."""
    # for example
    def do_something(self, *args, **kwargs):
        func1(*args)

This approach does have it's drawbacks, namely:

  • If by any chance your helper methods acts on an instance of some self-defined class, then this approach will break. Of course, you can pass-in the instance as an argument, but that is a very, very bad idea in terms of software engineering ideas and principles.
  • Also, if you want to inherit them once and have access to them without additional code for all of the ActualUsefulImplementedClass's subclasses, then this approach doesn't fit the bill.
  • Finally, if you want a strictly OOP approach, or don't want the helper functions to pollute your current module scope's namespace, then this isn't the best fit as well.
  1. Similar to the first approach stated above (number 1), but create another middle-level class that doesn't use the mix-in. It will be something like the following:
from abc import ABCMeta

class Abstract(metaclass=ABCMeta):
    def write(self):
        raise NotImplementedError()

class Mixin():
    def meth1(self, *args, **kwargs):
        """ do something here"""

class MiddleMan(Abstract):
    """ write your methods here. You will not have access to the helper methods of the mix-in class."""

class ActualUsefulImplementedClass(MiddleMan, Mixin):
    """ You will have both the actual method implementations and the helper methods here without much or any code."""

However, the above code will only work if you don't need the helper methods inside your methods' implementations and only need them outside of the class. If you need them inside the methods' code, then use the first approach. If you only need the helpers outside of the class, then use this approach.


Note: I use docstrings in the line immediately after the class or method definition line whenever applicable. It describes some of the abilities and limitations of the approach, so please read them as well.