30

I have an "abstract" class, such as:

class A:
    def do_some_cool_stuff():
        ''' To override '''
        pass

    def do_some_boring_stuff():
        return 2 + 2

And class B, subclassing A:

class B(A):
    def do_stuff()
        return 4

Is there any way to declare, that a method A.do_some_cool_stuff must be overriden, and, possibly that some warning should be raised while trying to create B-class object, when B had not implemented A.do_some_cool_stuff?

1

1 Answer 1

55

Yes, by defining A as an ABC (Abstract Base Class):

from abc import ABC, abstractmethod

class A(ABC):

    @abstractmethod
    def do_some_cool_stuff():
        ''' To override '''
        pass

    def do_some_boring_stuff():
        return 2 + 2

You can subclass A, but you can only create instances of such a subclass if the do_some_cool_stuff() method has a concrete implementation:

>>> from abc import ABC, abstractmethod
>>> class A(ABC):
...     @abstractmethod
...     def do_some_cool_stuff():
...         ''' To override '''
...         pass
...     def do_some_boring_stuff():
...         return 2 + 2
... 
>>> class B(A):
...     def do_stuff():
...         return 4
... 
>>> B()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class B with abstract methods do_some_cool_stuff
Sign up to request clarification or add additional context in comments.

4 Comments

Is __metaclass__ = ABCMeta necessary?
@RTD not in recent Python versions, but you want to then inherit from abc.ABC. I’ve adjusted the answer.
Thank you. Wondering why to inherit because it looks like using @abstractmethod decorators does the job? i.e., a subclass can't be instantiated unless all abstract methods are overridden first. Can you clarify what ABC inheritance adds please?
@RTD: no, @abstractmethod decorators are only part of the process. The ABC base class brings in the ABCMeta metaclass, and that takes care of gathering marked names into a frozenset of names to verify as implemented. See the Pure Python fallback implementation of ABCMeta.__new__, which builds the __abstractmethods__ for each class (this is called for each subclass created). You can't create instances of a class with a non-empty __abstractmethods__ value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.