Clases base abstractas en python

Clases abstractas en python: Obligar a una clase a implementar métodos.

Las clases abstractas pueden contener métodos abstractos: métodos sin implementación.
Los objetos no se pueden crear a partir de una clase abstracta. Una subclase puede implementar una clase abstracta.

Métodos abstractos en python

Una clase abstracta de python tiene métodos, pero no implementación.

Esto es similar a una interfaz en otros lenguajes.

La clase abstracta no se puede instanciar y una subclase debe implementar sus métodos.

Si tiene muchos objetos de un tipo similar, puede llamarlos de manera similar.

El siguiente ejemplo muestra una clase base abstracta.

from abc import ABC, abstractmethod

class AbstractClassExample(ABC):

    def __init__(self, value):
        self.value = value
        super().__init__()   

    @abstractmethod
    def do_something(self):
        pass

Si intenta crear un objeto, arroja un error:

obj = AbstractClassExample()

Este mensaje mostraría:

Traceback (most recent call last):
  File "example.py", line 13, in <module>
    obj = AbstractClassExample()
TypeError: Can't instantiate abstract class AbstractClassExample with abstract methods do_something

Las clases pueden heredar de un clase base abstracta en python

En este caso, podría heredar de AbstractClassExample.

Cada clase secundaria puede implementar los métodos de manera diferente.

class Example(AbstractClassExample):
    def do_something(self):
        print('something')

obj = Example(0)
obj.do_something()

Para resumir:

  • Una clase base abstracta no se puede instanciar (sin creación de objetos)
  • Una clase base abstracta tiene métodos pero no implementación
  • Las subclases pueden heredar de una clase base abstracta e implementar métodos

Ejemplo de clase abstractas en python

Entonces, ¿por qué usarías clases base abstractas en python?

Por un lado, su programa se vuelve fácil de extender.

Supongamos que amplía un programa de pintura y desea cargar un nuevo formato de imagen.

Entonces, todo lo que necesita hacer es implementar métodos de una clase base abstracta.

from abc import ABC, abstractmethod

class Image(ABC):
    def __init__(self, value):                                                                                                                     self.value = value                                                                                                                         super().__init__()

    @abstractmethod                                                                                                                        
    def load_image(self, filename):
        pass
        
    @abstractmethod
    def save_image(self, filename):
        pass

Puedes imaginar que cada formato de imagen necesita un código diferente.

Guardar un mapa de bits será diferente de guardar el formato webm.

Entonces cada clase puede hacer su propia implementación.

class Bitmap(Image):
    def load_image(self,filename):
        print('loading bitmap')

    def save_image(self,filename):
        print('save bitmap')

class Jpeg(Image):
    def load_image(self,filename):
        print('loading jpeg')

    def save_image(self,filename):
        print('saving jpeg')

Debido a que ambos heredan de la clase base abstracta, la estructura es la misma.

Segundo ejemplo

Imagine tener clases como Truck, Car y Bus.

Todos tendrían métodos como start(), stop(), accelerate().

Una clase abstracta (Automóvil) puede definir estos métodos abstractos pero no implementarlos.

truck.start()
truck.drive()
bus.start()
bus.drive()

Cuando se agrega una nueva clase, un desarrollador no necesita buscar métodos para implementar. Él / ella puede simplemente mirar la clase abstracta.

Si una de las subclases (camión, automóvil, autobús) pierde una implementación, Python arroja automáticamente un error.

Otro Ejemplo de clase abstracta con python

Crea una clase abstracta: AbstractAnimal. En la clase abstracta solo definimos los métodos sin implementación.

Luego puede crear clases concretas: clases que contienen una implementación. Vamos a crear una clase Duck que implemente AbstractAnimal. Usamos los mismos métodos, pero ahora agregamos una implementación.

import abc

class AbstractAnimal(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def walk(self):
        ''' data '''

    @abc.abstractmethod
    def talk(self):
        ''' data '''

class Duck(AbstractAnimal):
    name = ''

    def __init__(self, name):
        print('duck created.')
        self.name = name

    def walk(self):
        print('walks')

    def talk(self):
        print('quack')

obj = Duck('duck1')
obj.talk()
obj.walk()

Si olvidamos implementar uno de los métodos abstractos, Python arrojará un error.

Traceback (most recent call last):
  File "abst.py", line 27, in <module>
    obj = Duck('duck1')
TypeError: Can't instantiate abstract class Duck with abstract methods walk

Así es como puedes obligar a las clases a tener métodos. Esos métodos deben definirse en la clase abstracta.

Resumen

Podemos resumir este artículo en algunos puntos:

  • Puedes usar un clase base abstracta para crear una impresión azul.
  • Los objetos no se pueden crear a partir de una clase base abstracta.
  • Puede tener una subclase más que herede de la clase base abstracta.
  • En otros lenguajes de programación, se llama interfaz.

Te recomiendo mas entradas sobre que es la programacion orientada a objetos en python: