I'm trying to understand the benefits of using abstract base classes. Consider these two pieces of code:
Abstract base class:
from abc import ABCMeta, abstractmethod, abstractproperty
class CanFly:
    __metaclass__ = ABCMeta
    @abstractmethod
    def fly(self):
        pass
    @abstractproperty
    def speed(self):
        pass
class Bird(CanFly):
    def __init__(self):
        self.name = 'flappy'
    @property
    def speed(self):
        return 1
    def fly(self):
        print('fly')
b = Bird()
print(isinstance(b, CanFly))  # True
print(issubclass(Bird, CanFly))  #  True
Plain inheritance:
class CanFly(object):
    def fly(self):
        raise NotImplementedError
    @property
    def speed(self):
        raise NotImplementedError()
class Bird(CanFly):
    @property
    def speed(self):
        return 1
    def fly(self):
        print('fly')
b = Bird()
print(isinstance(b, CanFly))  # True
print(issubclass(Bird, CanFly))  # True
As you see, both methods support inflection using isinstance and issubclass.
Now, one difference I know is that, if you try to instantiate a subclass of an abstract base class without overriding all abstract methods/properties, your program will fail loudly.  However, if you use plain inheritance with NotImplementedError, your code won't fail until you actually invoke the method/property in question.
Other than that, what makes using abstract base class different?
 
    