Implementing interfaces in Python?

Question:

To my knowledge, there is no explicit built-in feature of Python that allows to implement interfaces. Consider the following situation:

I have a project with multiple classes. And some of them use a specific method. This method is not functionally or logically coherent with any of them, and technically should never appear there, not to mention that it’s the same method and it’s definitely a bad practice to copy and paste it in all these classes. Now I could create a class, and have all these classes inherit from it, so they can use this method… but then again, these classes have nothing in common with each other, and it would be silly for them to have a common superclass. I could create a separate class with this method, pass its instance as an argument everywhere and then invoke the method as a member function, but that also looks like a dirty move, and I would really like to do this in the most elegant way possible.

I think it is not useful to paste all this code here to emphasize the problem, I will just use a simplified model that focuses on what I want:

class 1():
    def class1_specific_method (self):
        common_method() 
    def common_method()
        #some code
        return
class 2():
    def class2_specific_method (self):
        common_method() 
    def common_method()
        #some code
        return

The common_method works exactly the same, is necessary in both situations, but is not cohesive with any of these classes. Normally, if it was Java, I would use some static class, or just implement an interface for those classes. Any ideas on how to make it look cleaner and more logical?

Answers:

I don’t see the problem of using inheritance, python is not java. I mean, python has multiple inheritance and it useful for mixins whose functionality is similar to java’s interfaces. For example if your inherit from a class Class0 you solve your problem as follows:

class Class0(object):
    ...

class Class1(Class0, CommonMethodsMixin):
    def class1_specific_method (self):
        common_method() 

class Class2(Class0, CommonMethodsMixin):
    def class2_specific_method (self):
        common_method() 

class CommonMethodsMixin(object):
    def common_method():
        ...

Given that you do not have any Class0 I do not see the problem of simply inheriting from CommonMethodsMixin class.

Answered By: se7entyse7en

Why not just make it a top-level function instead? If you choose to just ignore all the things Python brings you over something like Java (modules, top-level/first-class functions, duck typing), of course the lack of interfaces will seem inconvenient.

class 1():
    def class1_specific_method (self):
        common_method(self) 
class 2():
    def class2_specific_method (self):
        common_method(self) 

def common_method(obj)
    #some code
    return
Answered By: Mark Whitfield

An alternative to Interfaces is using Abstract Classes from the ABC module. Using it you can do:

from abc import ABCMeta
class AbstractClass(object):
   __metaclass__ = abc.ABCMeta
   def CommonMethod(self):
       print "Common Method for all subclasses!"
...
class MyClass(AbstractClass):
    pass

>>> obj = MyClass()
>>> obj.CommonMethod()
Common Method for all subclasses!

Now you have an abstract class from which your classes can inherit common behaviour. If you want to have multiple interfaces, you could use multiple inheritance with ABC.

However, multiple inheritance in Python should render useless the need for Interfaces in the first place (in theory, that is). In certain situations, ABCMeta can provide a mechanism similar to and Interface, but it also feels like you’re stretching the language a bit.

TL;DR: There are no interfaces in Python. ABC’s can provide a work arround.

Edit: There’s also zope.interface, but I’m not familiar with its usage.

Answered By: bconstanzo

I came across an approach in this article that I just had to share. Python has no native implementation of interfaces — but that’s where abstract classes and abstract methods come into play.

Approach One

It involves extending the AbstractBaseClasses class and using the @abstractmethod decorator.

The key characteristic of interfaces, is that they enforce the implementation of certain methods in classes, and by definition of abstract classes, this, is catered for.

Approach Two

Alternatively, one could also leverage TypeHints.

Reference: https://tomisin.dev/blog/how-to-implement-an-interface-in-python

Answered By: Tomisin Abiodun
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.