First off, read this PEP-3119. Lots of useful information about ABC's in python and why it was added in python.
To summarize, ABC's were added to formalize "Inspection" as the means of interacting with an object (as opposed to its more preferred sibling "Invocation"). Both of these are usage patterns for interacting with an object in OOP. Note, I said "formalize". Python supports inspection of objects but if we are to use it we need set rules/tests to go about doing so. The lack of such rules/tests in OO languages is actually one of the reasons why OOP theorists dont like inspection and prefer invocation.
As the PEP states,
This PEP proposes a particular strategy for organizing these tests known as Abstract Base Classes, or ABC. ABCs are simply Python classes that are added into an object’s inheritance tree to signal certain features of that object to an external inspector. Tests are done using isinstance(), and the presence of a particular ABC means that the test has passed.
Whats interesting to note is that ABC's in python are meant to be used with isinstance() and issubclass() ie, LBYL style rather than duck typing and EAFP.
Example usage:
from abc import ABC, abstractmethod
class Animal(ABC):
@property
@abstractmethod
def name(self):
"""Must define a getter in subclass"""
pass
@name.setter
@abstractmethod
def name(self, value):
"""Must define a setter in subclass"""
pass
@abstractmethod
def make_sound(self):
pass
# Concrete subclass
class Dog(Animal):
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
def make_sound(self):
return "Woof!"
dog = Dog("Buddy")
# If Dog inherits from Animal ABC then we can be sure that specific methods and
# properties are present. This can be good if we dont intend to follow duck typing.
if isinstance(dog, Animal):
print(f"{dog.name} says {dog.make_sound()}") # Buddy says Woof!
dog.name = "Rex"
print(f"Now it's {dog.name} saying {dog.make_sound()}") # Rex says Woof!