Whats is the practical difference from a Interface to a type and to an abstract class on OOP languages like python?

Python has duck typing :

If it walks like a duck and it quacks like a duck, then it must be a duck

Which means that this works :

class Duck:
    def quack(self):
        print("quack!")


class Car:
    def quack(self):
        print("vroum!")  # for example purposes


def make_it_quack(something):
    something.quack()  # don't care what it is, just that it quacks


make_it_quack(Duck())  # quack!
make_it_quack(Car())  # vroum!

Python at runtime will try to call the quack method on your object, and fails if it does not exist. But as long as the method exist (and the signature fit), Python does not care of the actual type of the object.

In other languages, you would have needed to define a base class (possibly abstract) that both child classes would have to inherit. And if there are multiple different sets of methods you want your object to have, either you 1) can do multiple-inheritance, 2) you build tall hierarchies of (abstract) base classes, or 3) you create lots of interfaces. Python does not need any of this, but it does not provide you static guarantees that your code type checks either.

If you want, there exist some ways to have more type checks in Python :

  • you can declare abstract base classes using the standard library abc
  • you can add type annotations to your code and use an external type checker (for exemple MyPy).

TL;DR : Python is duck-typed, but there is tooling if you want the guarantees that come with interface contracts.