Are there interfaces in python?

Asked

Viewed 14,381 times

6

In languages like PHP and Java, there are interfaces, which, when implemented in a class, requires it to contain the methods of this interface in the same way as they were declared.

Example in PHP:

<?php

interace UserInterface
{
   public function getName();
}


class User implements UserInterface
{
    // Se eu adiconar um parâmetro, vai gerar um erro
    public function getName()
    {
        return $this->name;
    }
}

class Scholl
{
     protected $users = array();
     /*
       Obriga a implementação de uma classe que implemente a 
        interface UserInterface
     */
     public function addUser(UserInterface $user)
     {
            $this->users[] = $user;
     }
}

In Python, there is an interface or there is some standard for this?

If there are no interfaces, there is some way to "force" a method to exist in a class?

There is a type induction in Python?

3 answers

19


In python is used Duck Typing, but if you need to force someone to implement certain methods if they inherit from your base classes you can use the ABC (Abstract base classes), but this is not very common (it is more common for those who write frameworks). Example:

import abc


class Shape(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def method_to_implement(self, input):
        return

If a class were made that inherited from Shape but did not implement the method method_to_implement would have a TypeError for example:

class Foo(Shape):
    pass

foo = Foo()

The above code would go up the following exception TypeError: Can't instantiate abstract class Foo with abstract methods method_to_implement

Note: in python 3.x the way to declare the metaclass of a class changes a bit:

import abc


class Shape(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def method_to_implement(self, input):
        return

Another way is to do as @Pablo Palaces suggested, work with Exception NotImplementedError (what is most common in enterprise applications).

class Shape(object):

    def method_to_implement(self, input):
        raise NotImplementedError()

However, in that case, the error would only go up when the method method_to_implement were called.

class Foo(Shape):
    pass


foo = Foo()
foo.method_to_implement('bar')

Another difference is that the mistake would be a NotImplementedError and not a TypeError.

  • The solution does not work in Python 3.

  • @Joãopaulooliveirafernandes on your first question (which you apparently deleted) yes, up an Exception, here’s an example http://pastebin.com/FeVZhAB7 but note that this code is written for python2

  • Yes, I deleted because it didn’t make sense since I tested it in Python 3. Here’s why it doesn’t work in 3 and a base to work: http://stackoverflow.com/questions/18513821/python-metaclass-understanding-the-with-metaclass/18513858#18513858

  • 1

    It’s simple, just change the basis of the class Shape for this syntax Shape(metaclass=abc.ABCMeta), for example http://pastebin.com/naYJc0iq

  • Still not pointing out any exceptions

  • Did you see the pastbin I sent? The first I drove in Python 2.7 and the second Rodei in Python 3.4, both went up exception...

  • Yes. Now it’s really good! You could edit your answer. Your solution is faster than @Pablo Palaces. UP!

  • 1

    Cool.. I’ll include the shape of py3

Show 3 more comments

8

Python does not have a unique syntax for determining an interface. What you can do is build an object that works like one, because, after all, interface is a concept and can be implemented anyway.

A simple and quick way is to use the exception NotImplementedError in a parent class:

class Animal:

    def andar(self):
        raise NotImplementedError("Animais precisam implementar andar")

Thus, so that the exception does not occur, all child classes of Animal will need to implement their own method andar():

>>> class Cachorro(Animal):
...     pass
... 
>>> c = Cachorro()
>>> c.andar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in andar
NotImplementedError: Animais precisam implementar andar

Note that Animal is a class like any other (without any extra syntax) and therefore you can do whatever you want with it, including putting non-abstractive methods, constants, etc... This can be good to avoid a very pharaonic architecture (interfaces + abstract classes in java) if your problem is simple, such as grouping in a single place all the logic/values/details common to a given group of classes. Remember, simple is better than complex.

  • Very good response - although more informative, the one that quotes the Abcs is "more correct" - but suddenly you could only quote them at the end of the reply for completeness purposes.

  • Since in python there is no difference between Pilot time and run time, I don’t consider this answer less complete. I prefer that answer because it’s clearer and more practical.

  • Also the other solution does not work in Python 3.

  • Just pointing out that the question did not specify the python version.

  • Its (@drgarcia1986) solution, to adapt, is better than this because this solution does not prevent the class to be instantiated. For now this solution is more robust.

3

Many Python programmers claim that others didn’t need Python interfaces - until they find someone who makes them use interfaces anyway (yes, there are people who will force you to use something you didn’t want, the great chiefs).

The above solutions solves in part, if you need your software components to be easily pluggable and extensible, there is a set of packages called ZCA (Zope Component Architecture) that basically use the packets zope.interface and zope., that facilitate the use of Python interfaces.

Here are some interesting links to their use:

  • 1

    Yes, ZCA can be very useful in many cases, principalmetne in really large applications.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.