Before abc was introduced you would see this frequently.

class Base(object):
    def go(self):
        raise NotImplementedError("Please Implement this method")


class Specialized(Base):
    def go(self):
        print "Consider me implemented"
Answer from kevpie on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › python › abstract-classes-in-python
Abstract Classes in Python - GeeksforGeeks
Abstract properties enforce that a subclass provides the property’s implementation. Abstract classes cannot be instantiated directly. This is because they contain one or more abstract methods or properties that lack implementations.
Published   September 3, 2025
🌐
DataCamp
datacamp.com › tutorial › python-abstract-classes
Python Abstract Classes: A Comprehensive Guide with Examples | DataCamp
January 22, 2025 - Python allows the creation of instances of WashingMachine while maintaining the contract specified in Appliance by implementing all of the abstract methods in WashingMachine. By guaranteeing that every feature specified in the abstract class is completely implemented in its concrete subclasses, this enforcement improves the codebase's integrity.
Discussions

What's the point of abstract classes if they don't enforce method signatures?
Typically abstract classes are only used for libraries, where the end user might want to provide their own version of a class. The "abstract" concept is mainly to help IDE's/linters so that when someone implements the class, they can see what needs to be implemented. That being said, abstract classes are mainly just to help others, they should never be used to check that an object is an instance of the abstract class. This is python, not a strong OO language, and as such, you shouldn't enforce any strong OO. Python is about duck typing. The typical python rule is: "we are all adults here", which typically means "guidelines" and not enforcement. The method signatures for ABC's are the same way. Someone probably should match the function signature, but if they don't want to, they shouldn't have to. More on reddit.com
🌐 r/Python
14
4
December 18, 2016
inheritance - Abstract methods in Python - Stack Overflow
I am having trouble in using inheritance with Python. While the concept seems too easy for me in Java yet up till now I have been unable to understand in Python which is surprising to me at least. I More on stackoverflow.com
🌐 stackoverflow.com
Calling abstract methods - Typing - Discussions on Python.org
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(… More on discuss.python.org
🌐 discuss.python.org
1
January 6, 2024
python - Is enforcing an abstract method implementation unpythonic? - Stack Overflow
When designing classes abstract methods can be very helpful. From what I know, Python does not have a mechanism for enforcing an inherited class to implement the abstract method. In my code (see ex... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Python
docs.python.org › 3 › library › abc.html
abc — Abstract Base Classes
Using this decorator requires that the class’s metaclass is ABCMeta or is derived from it. A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden. The abstract methods can be called using any of the normal ‘super’ call mechanisms.
🌐
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?

🌐
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
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 - Abstract classes and methods ensure that any subclass provides implementations for the specified methods, thus enforcing a certain design contract.
Find elsewhere
🌐
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 ...
Here’s how you can enforce this: This setup ensures that all payment methods implement the process_payment method. It creates more organized and readable code, encourages code reusability by placing common code in abstract base classes, and enhances flexibility. ... Abstract classes and methods are powerful tools in Python's OOP arsenal.
Top answer
1 of 4
15

Python actually does have abstract classes with abstact methods:

>>> import abc
>>> 
>>> class IFoo(object):
...     __metaclass__ = abc.ABCMeta
...     
...     @abc.abstractmethod
...     def foo(self):
...         pass
... 
>>> foo = IFoo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Cant instantiate abstract class IFoo with abstract methods foo
>>> class FooDerived(IFoo):
...     pass
... 
>>> foo = FooDerived()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Cant instantiate abstract class FooDerived with abstract methods foo
>>> class FooImplements(FooDerived):
...     def foo(self):
...         print "foo'ed"
... 
>>> foo = FooImplements()
>>> foo.foo()
foo'ed
>>> 

On the other hand, the fundamental question of "is this pythonic" is a bit harder to say. If your intent is to provide the abstract base class so that you can later check to make sure that values inherit from it, then no, that's not particularly pythonic, even though it's possible to make arbitrary types abstract subclasses of your baseclass. On the other hand, it's perfectly fine to provide an abstract baseclass that implements some functionality based upon the implementation provided in concrete subclasses. For example, collections.Sequence and collections.Mapping do just this for list like and dict like classes; subclasses can provide __getitem__ and can get __contains__ and others for free.

For certain, you should never use assert() except to document the expectations of code; If it's actually possible for the assert to fail, you shouldn't be using an assert. Optimized python (python -O script.py) does not check assertions.

Edit: more exposition:

If you are checking the type of a value:

def foo(bar):
    if not isinstance(bar, AbstractBaz):
        raise ValueError, ("bar must be an instance of AbstractBaz, "
                           "got %s" % type(bar))

If for some reason you can't use @abstractmethod, but still want that effect, you should raise NotImplementedError. You might want to do this because you actually do want instances of that class, some of which might not need to implement optional functionality. You still should account for the possibility that the function was called through super(). To a first approximation, that might look like this.

class Foo(object):
    def bar(self, baz):
        if self.bar.im_func == Foo.bar.im_func:
            raise NotImplementedError, "Subclasses must implement bar"
2 of 4
5

ABCs are an artifact of C++ and are contrary to duck-typing. If class Animal did not define speak it would do what you intend with no effort at all.

>>> class Animal(object):
...     pass
... 
>>> class Dog(Animal):
...     def speak(self):
...             print "bark"
... 
>>> animal = Animal()
>>> dog = Dog()
>>> animal.speak()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Animal' object has no attribute 'speak'
>>> dog.speak()
bark

C++ and related languages force you to create ABCs because the ABC is actually an interface description. Python eschews compiler-enforced interface declarations as they attempt to document – in code – a contract that is better enforced through extra-linguistic means.

🌐
Medium
medium.com › @aaron_imn › enforce-abstract-methods-signature-to-derived-classes-in-python-a21414943ce6
Enforce abstract methods signature to derived classes in Python | Medium
February 26, 2024 - In the example below, an abstract base class A has been defined that has an abstractmethod called a. The classes B and C have derived from A, whereas B follows the same signature of the abstract method a, while C does not. By running this script, you will receive a True followed by a False. Throughout using __subclasshook__ one can customize the output of callingissubclass on two given classes. Elaborately, the __subclasshook__ method receives two classes C1 and C2, and returns True if C1 is a subclass of C2.
🌐
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
11
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
🌐
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...
🌐
JetBrains
jetbrains.com › help › pycharm › implementing-methods-of-an-interface.html
Implement methods of an abstract class | PyCharm Documentation
April 10, 2025 - It's possible to implement methods decorated with @abstractmethod and methods that contain raise NotImplementedError.
🌐
GeeksforGeeks
geeksforgeeks.org › python › data-abstraction-in-python
Data Abstraction in Python - GeeksforGeeks
Abstract properties enforce that a subclass provides property’s implementation. Abstract classes cannot be instantiated directly. This is because they contain one or more abstract methods or properties that lack implementations.
Published   1 week ago
Top answer
1 of 1
8

You can't do what you want with just ABCMeta. ABC enforcement doesn't do any type checking, only the presence of an attribute with the correct name is enforced.

Take for example:

>>> from abc import ABCMeta, abstractmethod, abstractproperty
>>> class Abstract(object):
...     __metaclass__ = ABCMeta
...     @abstractmethod
...     def foo(self): pass
...     @abstractproperty
...     def bar(self): pass
... 
>>> class Concrete(Abstract):
...     foo = 'bar'
...     bar = 'baz'
... 
>>> Concrete()
<__main__.Concrete object at 0x104b4df90>

I was able to construct Concrete() even though both foo and bar are simple attributes.

The ABCMeta metaclass only tracks how many objects are left with the __isabstractmethod__ attribute being true; when creating a class from the metaclass (ABCMeta.__new__ is called) the cls.__abstractmethods__ attribute is then set to a frozenset object with all the names that are still abstract.

type.__new__ then tests for that frozenset and throws a TypeError if you try to create an instance.

You'd have to produce your own __new__ method here; subclass ABCMeta and add type checking in a new __new__ method. That method should look for __abstractmethods__ sets on the base classes, find the corresponding objects with the __isabstractmethod__ attribute in the MRO, then does typechecking on the current class attributes.

This'd mean that you'd throw the exception when defining the class, not an instance, however. For that to work you'd add a __call__ method to your ABCMeta subclass and have that throw the exception based on information gathered by your own __new__ method about what types were wrong; a similar two-stage process as what ABCMeta and type.__new__ do at the moment. Alternatively, update the __abstractmethods__ set on the class to add any names that were implemented but with the wrong type and leave it to type.__new__ to throw the exception.

The following implementation takes that last tack; add names back to __abstractmethods__ if the implemented type doesn't match (using a mapping):

from types import FunctionType

class ABCMetaTypeCheck(ABCMeta):
    _typemap = {  # map abstract type to expected implementation type
        abstractproperty: property,
        abstractstatic: staticmethod,
        # abstractmethods return function objects
        FunctionType: FunctionType,
    }
    def __new__(mcls, name, bases, namespace):
        cls = super(ABCMetaTypeCheck, mcls).__new__(mcls, name, bases, namespace)
        wrong_type = set()
        seen = set()
        abstractmethods = cls.__abstractmethods__
        for base in bases:
            for name in getattr(base, "__abstractmethods__", set()):
                if name in seen or name in abstractmethods:
                    continue  # still abstract or later overridden
                value = base.__dict__.get(name)  # bypass descriptors
                if getattr(value, "__isabstractmethod__", False):
                    seen.add(name)
                    expected = mcls._typemap[type(value)]
                    if not isinstance(namespace[name], expected):
                        wrong_type.add(name)
        if wrong_type:
            cls.__abstractmethods__ = abstractmethods | frozenset(wrong_type)
        return cls

With this metaclass you get your expected output:

>>> class Abstract(object):
...     __metaclass__ = ABCMetaTypeCheck
...     @abstractmethod
...     def foo(self): pass
...     @abstractproperty
...     def bar(self): pass
...     @abstractstatic
...     def baz(): pass
... 
>>> class ConcreteWrong(Abstract):
...     foo = 'bar'
...     bar = 'baz'
...     baz = 'spam'
... 
>>> ConcreteWrong()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class ConcreteWrong with abstract methods bar, baz, foo
>>> 
>>> class ConcreteCorrect(Abstract):
...     def foo(self): return 'bar'
...     @property
...     def bar(self): return 'baz'
...     @staticmethod
...     def baz(): return  'spam'
... 
>>> ConcreteCorrect()
<__main__.ConcreteCorrect object at 0x104ce1d10>
🌐
Python Course
python-course.eu › oop › the-abc-of-abstract-base-classes.php
20. The 'ABC' of Abstract Base Classes | OOP | python-course.eu
A class that is derived from an abstract class cannot be instantiated unless all of its abstract methods are overridden.
🌐
Real Python
realpython.com › python-interface
Implementing an Interface in Python – Real Python
February 21, 2024 - However, informal interfaces would be the wrong approach for larger applications. In order to create a formal Python interface, you’ll need a few more tools from Python’s abc module. To enforce the subclass instantiation of abstract methods, you’ll utilize Python’s builtin ABCMeta from the abc module.
🌐
Scaler
scaler.com › home › topics › abstract class in python
Abstract Class in Python - Scaler Topics
April 9, 2024 - The module we can use to create an abstract class in Python is abc(abstract base class) module. Abstract methods force the child classes to give the implementation of these methods in them and thus help us achieve abstraction as each subclass ...
🌐
Python.org
discuss.python.org › python help
Why does using property and abstractmethod not enforce properties in child? - Python Help - Discussions on Python.org
October 14, 2021 - Example: from abc import ABC, abstractmethod class AbstractExample(ABC): @property @abstractmethod def some_prop(self): pass class ConcreteExample(AbstractExample): def some_prop(self): return None c = ConcreteExample() # this does not raise