Is there any interfaces in python?

3

In languages like PHP and Java, there are interfaces , which, when implemented in a class, forces it to contain the methods of this interface, just 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, is there an interface or is there any standard for this?

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

Is type induction in Python?

    
asked by anonymous 03.07.2015 / 17:50

3 answers

9

In python you use duck typing , but if you need to force someone to implement certain methods if they inherit from their base classes you can use ABC (abstract base classes) , but this is not very common (it's more common for who writes frameworks). Example:

import abc


class Shape(object):
    __metaclass__ = abc.ABCMeta

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

If a class was inherited from Shape but did not implement method method_to_implement would have a TypeError eg:

class Foo(Shape):
    pass

foo = Foo()

The above code would raise 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 little:

import abc


class Shape(metaclass=abc.ABCMeta):

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

Another way is to do as @Pablo Palacios suggested, working with the exception NotImplementedError (which is more common in corporate applications).

class Shape(object):

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

However, in this case, the error would only increase when the method_to_implement method was called.

class Foo(Shape):
    pass


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

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

    
03.07.2015 / 18:38
5

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

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

class Animal:

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

So, for the exception not to occur, all child classes of Animal will need to implement their own andar() method:

>>> 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-abstract methods, constants, etc ... This may be good to avoid a If you have a problem with simple pharaonic architecture (interfaces + abstract classes in java), you can simply group all the logic / values / details common to a certain class of classes in one place. Remember, simple is better than complex.

    
03.07.2015 / 21:46
2

Many Python programmers claim that others did not need Python interfaces - until they found someone to make use of interfaces anyway (yes, there are people who will force you to use something you did not want, the big bosses ).

The solutions above solve in parts, if you need components of your software to be easily pluggable and extensible, there is a set of packages called Zope Component Architecture ) that basically use < > zope.interface and zope.component , which make it easier to use Python Interfaces.

Here are some interesting links to using them:

02.08.2015 / 04:22