From the docs:

A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden.

Conversely, this means that any class with no abstract methods or properties like your AbstractClass can be instantiated.


If you want to disallow instantiation of the topmost parent class, you can write a custom class that performs a type check in its __new__ method:

class SubclassOnlyABC(object):
    __metaclass__ = abc.ABCMeta

    def __new__(cls, *args, **kwargs):
        if cls.__bases__ == (SubclassOnlyABC,):
            msg = 'Abstract class {} cannot be instantiated'.format(cls.__name__)
            raise TypeError(msg)

        return super(SubclassOnlyABC, cls).__new__(cls, *args, **kwargs)
class AbstractClass(SubclassOnlyABC):
    pass

class ChildClass(AbstractClass):
    pass

ChildClass()  # works because it's a child class of an abstract class
AbstractClass()  # throws TypeError because its parent class is "object"

You can also write a __new__ method that prevents instantiation of classes with no abstract methods:

class NonEmptyABC(object):
    __metaclass__ = abc.ABCMeta

    def __new__(cls, *args, **kwargs):
        # check if ANY abstractmethod exists
        for parentcls in cls.__mro__:
            if any(getattr(attr, '__isabstractmethod__', False)
                               for attr in vars(parentcls).values()):
                break
        else:
            msg = 'Abstract class {} cannot be instantiated'.format(cls.__name__)
            raise TypeError(msg)

        return super(NonEmptyABC, cls).__new__(cls, *args, **kwargs)
class EmptyAbstractClass(NonEmptyABC):
    pass

class NonemptyAbstractClass(NonEmptyABC):
    @abc.abstractmethod
    def foo(self):
        pass

class NonemptyChild(NonemptyAbstractClass):
    def foo(self):
        pass

NonemptyChild()  # works because "foo" is an abstractmethod
EmptyAbstractClass()  # throws TypeError because there are no abstractmethods
Answer from Aran-Fey on Stack Overflow
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ what's the point of abc & @abstractmethod
r/learnpython on Reddit: What's the point of ABC & @abstractmethod
July 27, 2021 -

Hello. In this first example, I have a short and straightforward code w/ a class for interface. It doesn't inherit from ABC and doesn't have any abstract methods.

class Abs():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    def go_to(self):
        return f"{self.name} is going to {self.place}."
        
class Teacher(Abs):
    place = "work"

class Student(Abs):
    place = "school"
    
t1 = Teacher("James", 56)
s1 = Student("Tim", 15)

print(t1.go_to())
print(s1.go_to())

In this second example, it's the exact opposite.

from abc import ABC, abstractmethod

class Abs(ABC):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    @abstractmethod
    def go_to(self):
        ...
        
class Teacher(Abs):
    place = "work"
    
    def go_to(self):
        return f"{self.name} is going to {self.place}."

class Student(Abs):
    place = "school"
    
    def go_to(self):
        return f"{self.name} is going to {self.place}."
    
t1 = Teacher("James", 56)
s1 = Student("Tim", 15)

print(t1.go_to())
print(s1.go_to())

Both examples have the same output. In the tutorials/articles I've read, most times the second example is preferred. In the abstract class, abstract methods get defined and decorated, and then in the inheriting classes they all get redefined with the rest of the logic. What's the point of creating a class w/ abstract methods which later on we redefine? What issue does that solve? Why not just proceed as in the first example - simple, less code, one parent class for the interface, if we need to add other details, we do so in the base class once and handle the extra logic with that additional info there. Doesn't the first code present a better example of loose coupling - just one connection between parent and child classes, where in the second code, we get connections between parent/child in every method that we redefine? I feel like I'm missing something, because to me, the second example is much more spaghetti-like. If anyone can explain why it's a good practice to redefine abstract methods that would be nice. Also, is it a bad practice to write code as in the first example, w/o ABC+@abstractmethod in the parent class?
Thanks.

Top answer
1 of 5
10
So your examples are a bit problematic because you would never use @abstractmethod in that situation. In your example there is no reason not to define the function only in the parent class--the parent knows everything it needs in order to execute the function, and the children don't change the execution at all. Also, Abs is a terrible name for a class. @abstractmethod is for when you: Require all children to have a method Don't have enough information to define that method in the parent Essentially, it "requires" child classes to define this method. This allows you to include the method in your parent interface so you can document it but raises a sensible error if the child doesn't re-define it. This is mostly useful for parent classes that will never have direct instances--only instances of subclasses. Consider designing a shooter game like Doom or Quake. You might represent various objects and enemies as class instances. To keep the game synced, every clock tick all the objects need to "update" themselves. Enemies might move around, lights might blink, and items might recharge. They all need to do something, but what they do is completely unique to each class. In a case like this, you might define the update() method in the parent Object class. This is mostly a convenience feature--you can write the same code perfectly well without it. However, it allows you to refer to all objects collectively (isinstance(o, Object)) through the parent class, and still ensure that update() exists, even though the parent doesn't know what to do with it. You could easily define update() in the parent and have it do nothing, but this prevents errors from being raised if you call this on a child class that hasn't re-defined the method.
2 of 5
3
let's imagine a List interface - we'll have the operations of append and pop class List(ABC): @abstractmethod def append(self, val): pass @abstractmethod def pop(self): pass now we could create class LinkedList(List) and class ArrayList(List) where we'd implement the methods for both of the list types the reason for using ABC and @abstractmethod is because it doesn't make sense to be able to be able to instantiate a List - that doesn't have an implementation. it only describes what behaviour an implementation should have to provide. think of it as providing a contract by which all users of an object know what behaviour to expect abstract classes and methods are more useful in languages such as java where you can't rely on duck typing void doThing(List list) this would take any subclass of List and be checked at compile time to have the expected methods of append and pop
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ library โ€บ abc.html
abc โ€” Abstract Base Classes
The abc module also supports the following legacy decorators: ... Added in version 3.2. Deprecated since version 3.3: It is now possible to use classmethod with abstractmethod(), making this decorator redundant.
Top answer
1 of 5
11

From the docs:

A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden.

Conversely, this means that any class with no abstract methods or properties like your AbstractClass can be instantiated.


If you want to disallow instantiation of the topmost parent class, you can write a custom class that performs a type check in its __new__ method:

class SubclassOnlyABC(object):
    __metaclass__ = abc.ABCMeta

    def __new__(cls, *args, **kwargs):
        if cls.__bases__ == (SubclassOnlyABC,):
            msg = 'Abstract class {} cannot be instantiated'.format(cls.__name__)
            raise TypeError(msg)

        return super(SubclassOnlyABC, cls).__new__(cls, *args, **kwargs)
class AbstractClass(SubclassOnlyABC):
    pass

class ChildClass(AbstractClass):
    pass

ChildClass()  # works because it's a child class of an abstract class
AbstractClass()  # throws TypeError because its parent class is "object"

You can also write a __new__ method that prevents instantiation of classes with no abstract methods:

class NonEmptyABC(object):
    __metaclass__ = abc.ABCMeta

    def __new__(cls, *args, **kwargs):
        # check if ANY abstractmethod exists
        for parentcls in cls.__mro__:
            if any(getattr(attr, '__isabstractmethod__', False)
                               for attr in vars(parentcls).values()):
                break
        else:
            msg = 'Abstract class {} cannot be instantiated'.format(cls.__name__)
            raise TypeError(msg)

        return super(NonEmptyABC, cls).__new__(cls, *args, **kwargs)
class EmptyAbstractClass(NonEmptyABC):
    pass

class NonemptyAbstractClass(NonEmptyABC):
    @abc.abstractmethod
    def foo(self):
        pass

class NonemptyChild(NonemptyAbstractClass):
    def foo(self):
        pass

NonemptyChild()  # works because "foo" is an abstractmethod
EmptyAbstractClass()  # throws TypeError because there are no abstractmethods
2 of 5
10

I usually just declare the base class's __init__ with @abc.abstractmethod. If my base class does not have an __init__, I add a trivial one.

Something like this:

class AbstractClass(abc.ABC):
    @abc.abstractmethod
    def __init__(self):
        pass

    # other useful non-abstract methods...


class ChildClass(AbstractClass):
    def __init__(self):
        pass


if __name__ == '__main__':
    child = ChildClass()  # allowed
    abstract = AbstractClass()  # TypeError
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 46726272 โ€บ how-to-create-abstract-classes-using-abc-without-using-an-abstract-method
python - How to create abstract classes using abc without using an abstract method? - Stack Overflow
from abc import ABC, abstractmethod class A(ABC): @abstractmethod def foo(self): print('foo') class B(A): pass obj = B() This will fail because B has not defined the method foo. This mimics the abstract method functionality in Java.
Top answer
1 of 13
760

Use the abc module to create abstract classes. Use the abstractmethod decorator to declare a method abstract, and declare a class abstract using one of three ways, depending upon your Python version.

In Python 3.4 and above, you can inherit from ABC. In earlier versions of Python, you need to specify your class's metaclass as ABCMeta. Specifying the metaclass has different syntax in Python 3 and Python 2. The three possibilities are shown below:

Copy# Python 3.4+
from abc import ABC, abstractmethod
class Abstract(ABC):
    @abstractmethod
    def foo(self):
        pass
Copy# Python 3.0+
from abc import ABCMeta, abstractmethod
class Abstract(metaclass=ABCMeta):
    @abstractmethod
    def foo(self):
        pass
Copy# Python 2
from abc import ABCMeta, abstractmethod
class Abstract:
    __metaclass__ = ABCMeta

    @abstractmethod
    def foo(self):
        pass

Whichever way you use, you won't be able to instantiate an abstract class that has abstract methods, but will be able to instantiate a subclass that provides concrete definitions of those methods:

>>> Abstract()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Abstract with abstract methods foo
>>> class StillAbstract(Abstract):
...     pass
... 
>>> StillAbstract()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class StillAbstract with abstract methods foo
>>> class Concrete(Abstract):
...     def foo(self):
...         print('Hello, World')
... 
>>> Concrete()
<__main__.Concrete object at 0x7fc935d28898>
2 of 13
152

The old-school (pre-PEP 3119) way to do this is just to raise NotImplementedError in the abstract class when an abstract method is called.

Copyclass Abstract(object):
    def foo(self):
        raise NotImplementedError('subclasses must override foo()!')

class Derived(Abstract):
    def foo(self):
        print 'Hooray!'

>>> d = Derived()
>>> d.foo()
Hooray!
>>> a = Abstract()
>>> a.foo()
Traceback (most recent call last): [...]

This doesn't have the same nice properties as using the abc module does. You can still instantiate the abstract base class itself, and you won't find your mistake until you call the abstract method at runtime.

But if you're dealing with a small set of simple classes, maybe with just a few abstract methods, this approach is a little easier than trying to wade through the abc documentation.

๐ŸŒ
CodeSignal
codesignal.com โ€บ learn โ€บ courses โ€บ revisiting-oop-concepts-in-python โ€บ lessons โ€บ understanding-abstract-classes-and-abstract-methods-in-python
Codesignal
By mastering abstract classes and abstract methods, you'll be able to easily add new types of derived classes without modifying existing code โ€” a key principle of software design. For example, consider the following implementation, where you adhere to the defined interface without any modifications to the existing Shape class:
Find elsewhere
๐ŸŒ
GitHub
github.com โ€บ microsoft โ€บ pyright โ€บ issues โ€บ 2547
No errors when using `@abstractmethod` on non-ABC class or when instantiating such class ยท Issue #2547 ยท microsoft/pyright
November 6, 2021 - To Reproduce # pyright: strict from abc import abstractmethod class MyAbstract: # does not inherit from ABC @abstractmethod # no error def do_something(self): pass c = MyAbstract().do_something() # also no error Expected behavior An erro...
Author ย  Tomaz-Vieira
๐ŸŒ
Python.org
discuss.python.org โ€บ python help
AbstractMethods and NotImplementedError - Python Help - Discussions on Python.org
December 22, 2022 - Are there any experts on the use of ABCs and abstractmethod who could weigh in on a documentation issue please? The documentation for the exception says that abstract methods should raise NotImplementedError. Obviously this is not mandatory. Abstract methods can have default implementations.
๐ŸŒ
Real Python
realpython.com โ€บ ref โ€บ glossary โ€บ abstract-base-class
abstract base class (ABC) | Python Glossary โ€“ Real Python
from abc import ABC, abstractmethod class Animal(ABC): @abstractmethod def speak(self): pass def jump(self): return f"{self.__class__.__name__} is jumping" Animal is an abstract base class with an abstract method .speak() and a regular method .jump(). Subclasses must implement all methods marked with @abstractmethod: ... >>> from animals import Animal >>> class Dog(Animal): ... pass >>> Dog() Traceback (most recent call last): ... TypeError: Can't instantiate abstract class Dog โฎ‘ without an implementation for abstract method 'speak'
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ abstract-classes-in-python
Abstract Classes in Python - GeeksforGeeks
Abstract Base Class: Animal is an abstract class that inherits from ABC (Abstract Base Class). This class cannot be instantiated directly because it contains an abstract method sound(). The @abstractmethod decorator is used to mark sound() as an abstract method.
Published ย  December 13, 2024
๐ŸŒ
Python.org
discuss.python.org โ€บ typing
Calling abstract methods - Typing - Discussions on Python.org
January 6, 2024 - PEP 544 indicates that a type checker should generate an error if a class that explicitly derives from the protocol attempts to call a method through super() if that method is unimplemented in the protocol. class Proto(Protocol): def method(self) -> None: ... class Impl(Proto): def method(self) -> None: super().method() # Type checker error This makes sense because the method in the protocol is effectively abstract.
๐ŸŒ
Medium
leapcell.medium.com โ€บ elegant-abstractions-mastering-abstract-base-classes-in-advanced-python-bf3739dd815e
Elegant Abstractions: Mastering ABCs in Advanced Python | by Leapcell | Medium
May 2, 2025 - Here, _validate uses NotImplementedError instead of @abstractmethod, indicating that it is an optional extension point, not a required interface to be implemented. Mainstream Python code checking tools (pylint, flake8) all provide good support ...
๐ŸŒ
Reddit
reddit.com โ€บ r/python โ€บ what's the point of abstract classes if they don't enforce method signatures?
r/Python on Reddit: What's the point of abstract classes if they don't enforce method signatures?
December 18, 2016 -

I was surprised to see the Python abstract classes don't enforce anything except the override and method name. I can see why in Python enforcing parameter data-types would probably not work, but the number of parameters and parameter names ought to be enforced.

I've always thought the point of abstract classes was to ensure that any inheritor of the class would would work with existing code to run the abstract methods defined in the super class. The whole point was to enforce method signatures.

It seems to me that Python's implantation of abstract classes has very little utility. Does anyone even use them? What for?

Top answer
1 of 2
7

I've used this before in cases where it was possible to have the concrete implementation, but I wanted to force subclass implementers to consider if that implementation is appropriate for them.

One specific example: I was implementing an abstract base class with an abstract factory method so subclasses can define their own __init__ function but have a common interface to create them. It was something like

class Foo(ABC):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    @classmethod
    @abstractmethod
    def from_args(cls, a, b, c) -> "Foo":
        return cls(a, b, c)

Subclasses usually only need a subset of the arguments. When testing, it's cumbersome to access the framework which actually uses this factory method, so it's likely someone will forget to implement the from_args factory function since it wouldn't come up in their usual testing. Making it an abstractmethod would make it impossible to initialize the class without first implementing it, and will definitely come up during normal testing.

2 of 2
4

The short answer is: Yes.

As described in the Python Documentation of abc:

The abstract methods can be called using any of the normal โ€˜superโ€™ call mechanisms

PEP3119 also discussed this behavior, and explained it can be useful in the super-call:

Unlike Javaโ€™s abstract methods or C++โ€™s pure abstract methods, abstract methods as defined here may have an implementation. This implementation can be called via the super mechanism from the class that overrides it. This could be useful as an end-point for a super-call in framework using cooperative multiple-inheritance [7], [8].

Actually, what the @abstractmethod decorator all do is setting the function's __isabstractmethod__ attribute to True (you can see the implementation code here). And the cooperation of both ABC and @abstractmethod can prevent the instantiation of an abstract class.

So, you can do whatever a normal method can do in an abstract method.

๐ŸŒ
Python Forum
python-forum.io โ€บ thread-34477.html
Abstraction Module (ABC)
Greetings, I started learning python about 6 months ago. I came from various other languages. So, the things that cause me the most difficulty are Abstraction, protected, private methods and properties and decorators. 1. In my example below, from...
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.

๐ŸŒ
Learnscript
learnscript.net โ€บ en โ€บ python โ€บ classes โ€บ abstract-classes
Introduction to Python Abstract Classes and Abstract Methods; Define and Implement Python Abstract Classes and Abstract Methods - Python Tutorial | Learn
The @abstractmethod decorator should be written after related decorators (@classmethod, @staticmethod, @property, etc.) to avoid raising the exception AttributeError. Since ABCMeta checks for implementations of Python abstract methods or attributes only when creating an instance, Python abstract class methods and abstract static methods, or abstract class attributes that are essentially methods, can be called directly without ...