# data[].attributes.body
CLASES ABSTRACTAS: Una clase abstracta no es instanciada, sirve como plantilla para las subclases.

METACLASES: De la misma manera que las Clases son una plantilla para la creación de objetos, las Metaclases son una plantilla para la creación de Clases. A veces a las Metaclases se las llama "fábricas de clases"

# data[].attributes.body
Una clase abstracta funciona como una interfaz en Java, que te permite diseñar la estructura que va a tener cualquier clase que se base en esta clase abstracta
Una metaclase nos permite crear de manera dinámica clases

# data[].attributes.body
Clase abstracta: aquella que se declara pero no contiene implementaciones; cada subclase debe tener su propia implementación. Funciona como una plantilla para las subclases

Metaclase: clase cuyas instancias son clases. La metaclase define el comportamiento de ciertas clases y sus instancias.

# data[].attributes.body
•Investigar acerca de los conceptos de Clases Abstractas y Metaclases.

# data[].attributes.body
Clases abstractas
En resumen, las clases abstractas son clases que no se pueden instanciar. Este es el caso porque las clases abstractas no especifican la implementación de características. Más bien, solo especifica las firmas del método y los tipos de propiedad (a veces), y cada clase secundaria debe proporcionar su propia implementación. Tenga en cuenta que todavía es posible proporcionar alguna implementación. Por ejemplo, una clase abstracta puede implementar un constructor predeterminado.

Metaclases

Puede pensar en las clases como modelos para la creación de objetos, y estaría en lo cierto. Pero en Python, las clases en sí mismas son objetos. Las metaclases son clases para clases y proporcionan planos para la creación de las mismas.

# data[].attributes.body
Clase Abstracta
Una clase abstracta tiene como objetivo definir una función / comportamiento común que múltiples subclases pueden heredar sin tener que implementar toda la clase abstracta.
MetaClases
Una metaclase define el comportamiento de una clase.

# data[].attributes.body
·Las clases abstractas no pueden ser instanciadas. Simplemente proporcionan una interfaz para las subclases derivadas y evitando así la duplicación de código.

·Las metaclases proporcionan planos para la creación de clases, es decir, "las metaclases son clases para clases".

# data[].attributes.body
Clases abstractas:
Son clases que no se pueden instanciar. Este es el caso porque las clases abstractas no especifican la implementación de características. Más bien, solo especifica las firmas del método y los tipos de propiedad (a veces), y cada clase secundaria debe proporcionar su propia implementación.

Metaclases:
Las metaclases son clases para clases. Las metaclases proporcionan planos para la creación de clases. Cada clase tiene una metaclase por defecto (se llama type)

# data[].attributes.body
-Una clase abstracta es una clase que nos permite definir un concepto de clase que nos puede servir de guia para desarrollar desde ahí el resto de clases relacionadas con ese concepto

-Una metaclase es una clase que definimos la cual tiene la mayor parte de la información y metodos/funciones de una rama de clases, la clase padre.

# data[].attributes.body
Las clases abstractas son clases que no se pueden instanciar. Sin embargo,  las metaclases son clases para clases. Es decir, las metaclases proporcionan planos para la creación de clases. Las instancias de una metaclase son clases en vez de objetos. Cada clase tiene una metaclase por defecto (se llama type).

# data[].attributes.attachment_link.readable_text
Python de forma nativa no soporta clases abstractas, pero eso no significa que no existan. A partir de la versión 2.6, Python trae el módulo abc ( abstract base classes) de acuerdo a PEP 3119, que consigue emular la abstracción de clases mediante metaclases y decoradores Python.

Metaclases

Un buen artículo muy recomendable que consigue explicar el mundillo de las metaclases sin pegarse un tiro en la cabeza, es este de crysol Ahí va la virgen! Metaclases! (con Python). Pero para hacerse una idea, diremos que una metaclase es una clase cuyas instancias son clases en lugar de objetos.

Es decir, si para construir un objeto usas una clase, para construir una clase usas una metaclase. Es importante entender que en Python todo es un objeto (incluso las clases, los modulos, los tipos de datos, etc..) y por lo tanto las clases, al ser objetos, son instancias de una metaclase.

En el caso que nos ocupa, es interesante porque permite modificar el comportamiento o características de una clase en el momento de su creación.

Decoradores

Respecto a los decoradores pues prefiero recomendaros un artículo de la casa 😉 Decoradores Python. A modo de resumen diremos que un decorador Python permite añadir funcionalidad extra a una función mediante un wrapper (envoltorio).

Clases abstractas en Python

Para empezar. Definiremos un método abstracto mediante el uso del decorador @abstractmethod. Al instanciar la clase... ¡Sorpresa! ha funcionado. Python no se queja.

>>> import abc
...
... class Vehicle(object):
...     @abc.abstractmethod
...     def who_are_you(self):
...         print "I'm a vehicle and also an abstract method"
...
... vehicle = Vehicle()
... vehicle.who_are_you()
I'm a vehicle and also an abstract method
>>>

Para que el invento funcione, la clase Vehicle tiene que heredar de la metaclase ACBMeta. Con un poco de 'azucar sintáctico' ( ¿what?) mediante __metaclass__ es fácil. Ahora Python hace lo esperado, se queja porque no es posible instanciar una clase con métodos abstractos.

>>> import abc
... from abc import ABCMeta
...
... class Vehicle(object):
...     __metaclass__ = ABCMeta
...
...     @abc.abstractmethod
...     def who_are_you(self):
...         print "I'm a vehicle and also an abstract method"
...
... vehicle = Vehicle()
... vehicle.who_are_you()
Traceback (most recent call last):
  File "<pyshell#6>", line 11, in <module>
    vehicle = Vehicle()
TypeError: Can't instantiate abstract class Vehicle with abstract methods who_are_you
>>>

Para curiosos. En el repositorio oficial está la implementación de la metaclase ABCMeta. Ahora vamos a crear una clase Car que herede de Vehicle y que sobreescriba el método abstracto.

>>> import abc
... from abc import ABCMeta
...
... class Vehicle(object):
...     __metaclass__ = ABCMeta
...
...     @abc.abstractmethod
...     def who_are_you(self):
...         print "I'm a vehicle and also an abstract method"
...
... class Car(Vehicle):
...
...     def __init__(self):
...         Vehicle.__init__(self)
...
...     def who_are_you(self):
...         print "I'm a car"
...
... car = Car()
... car.who_are_you()
I'm a car
>>>

Como curiosidad, podemos hacer 'trampas' e invocar al método abstracto mediante el uso de super().

>>> import abc
... from abc import ABCMeta
...
... class Vehicle(object):
...     __metaclass__ = ABCMeta
...
...     @abc.abstractmethod
...     def who_are_you(self):
...         print "I'm a vehicle and also an abstract method"
...
... class Car(Vehicle):
...
...     def __init__(self):
...         Vehicle.__init__(self)
...
...     def who_are_you(self):
...         super(Car, self).who_are_you()
...         print "I'm a car"
...
... car = Car()
... car.who_are_you()
I'm a vehicle and also an abstract method
I'm a car
>>>

Con el decorador @abstractproperty podemos crear propiedades abstractas. Aquí un ejemplo.

>>> import abc
... from abc import ABCMeta
...
... class Vehicle(object):
...     __metaclass__ = ABCMeta
...
...     @abc.abstractmethod
...     def who_are_you(self):
...         print "I'm a vehicle and also an abstract method"
...
...     @abc.abstractproperty
...     def color(self):
...         pass
...
... class Car(Vehicle):
...
...     def __init__(self):
...         Vehicle.__init__(self)
...
...     def who_are_you(self):
...         print "I'm a car"
...
...     @property
...     def color(self):
...         return "red"
...
... car = Car()
... car.who_are_you()
... print "my color is", car.color
I'm a car
my color is red
>>>

El anterior ejemplo definimos una propiedad de lectura. También es posible crear propiedades abstractas de lectura y escritura (getter & setter) pero esto solo es posible hacerlo sin 'azúcar sintáctico'

>>> import abc
... from abc import ABCMeta
...
... class Vehicle(object):
...     __metaclass__ = ABCMeta
...
...     @abc.abstractmethod
...     def who_are_you(self):
...         print "I'm a vehicle and also an abstract method"
...
...     def get_color(self):
...         pass
...
...     def set_color(self, value):
...         pass
...
...     color = abc.abstractproperty(get_color, set_color)
...
... class Car(Vehicle):
...
...     def __init__(self):
...         Vehicle.__init__(self)
...         self._color = "red"
...
...     def who_are_you(self):
...         print "I'm a car"
...
...     @property
...     def color(self):
...         return self._color
...
...     @color.setter
...     def color(self, value):
...         self._color = value
...
... car = Car()
... car.color = "blue"
... car.who_are_you()
... print "my color is", car.color
I'm a car
my color is blue
>>>

Aparte de escribir de vez en cuando en este blog y contribuir en proyectos open source. Profesionalmente me dedico al desarrollo de aplicaciones, administración de bases de datos, gestión de servicios TIC y soporte al usuario.

# data[].attributes.attachment_link.description
Python de forma nativa no soporta clases abstractas, pero eso no significa que no existan. A partir de la versión 2.6, Python trae el módulo abc (abstract base classes) de acuerdo a PEP 3119, que consigue emular la abstracción de clases mediante metaclases y decoradores Python.

# data[].attributes.body
Clase abstracta: No tiene instanciaciones, si no que su fin es que otras clases extiendan de ella

Metaclase: Sus instancias son Clases

# data[].attributes.body
Clases abstractas: las clases abstractas son clases que no se pueden instanciar. Este es el caso porque las clases abstractas no especifican la implementación de características. Más bien, solo especifica las firmas del método y los tipos de propiedad (a veces), y cada clase secundaria debe proporcionar su propia implementación. Tenga en cuenta que todavía es posible proporcionar alguna implementación. Por ejemplo, una clase abstracta puede implementar un constructor predeterminado.

metaclases: En programación orientada a objetos, una metaclase es una clase cuyas instancias son clases. En otras palabras, como los objetos son instancias de una clase, las clases son instancias de una metaclase.

# data[].attributes.body
Las clases abstractas son clases que no se pueden instanciar. Este es el caso porque las clases abstractas no especifican la implementación de características. Más bien, solo especifica las firmas del método y los tipos de propiedad (a veces), y cada clase secundaria debe proporcionar su propia implementación. Tenga en cuenta que todavía es posible proporcionar alguna implementación. Por ejemplo, una clase abstracta puede implementar un constructor predeterminado.