¿Como se crean clases abstractas con python?.
Voy a explicar cual es la forma correcta de definir una clase abstracta y heredar de ella. El procedimiento general es:
Tomemos como ejemplo el siguiente código:
Lo primero que hacemos es importar del módulo abc la clase ABCMeta y el decorador abstractmethod.
La clase ABCMeta es la metaclase que utilizamos para definir las clases abstractas, nos aporta una serie de funcionalidades.
Una vez hemos asignada la metaclase, definimos un método abstracto que deberá ser implementado por las subclases, el método bar.
De momento nos olvidamos del método __subclasshook__.
Posteriormente definimos la clase que concretará a la clase abstracta implementando el método abstracto.
Para terminar se registra como subclase de la clase abstracta con el método register. Con esto hacemos que la sentencia issubclass(some_var, AbstracFoo) devuelva True.
Como hemos visto, para que se considere subclase de la clase abstracta la clase concreta debe registrarse como subclase. Pero, ¿que pasa si queremos que cualquier otra clase sea considerada subclase de la abstracta y no la hemos registrado como subclase?
Para este problema tenemos el método __subclasshook__, que personalizará el comportamiento de issubclass sin necesidad de tener que invocar a register previamente. Este método debe devolver True, False o NotImplemented.
Voy a explicar cual es la forma correcta de definir una clase abstracta y heredar de ella. El procedimiento general es:
- Definir una clase abstracta utilizando una metaclase.
- Definir la subclase de la clase abstracta (sin herencia).
- Registrar esta última clase como subclase de la clase abstracta.
Tomemos como ejemplo el siguiente código:
from abc import ABCMeta, abstractmethod
class AbstractFoo:
__metaclass__ = ABCMeta
@abstractmethod
def bar(self):
pass
@classmethod
def __subclasshook__(cls, C):
return NotImplemented
class Foo(object):
def bar(self):
print "hola"
AbstractFoo.register(Foo)
Lo primero que hacemos es importar del módulo abc la clase ABCMeta y el decorador abstractmethod.
La clase ABCMeta es la metaclase que utilizamos para definir las clases abstractas, nos aporta una serie de funcionalidades.
Una vez hemos asignada la metaclase, definimos un método abstracto que deberá ser implementado por las subclases, el método bar.
De momento nos olvidamos del método __subclasshook__.
Posteriormente definimos la clase que concretará a la clase abstracta implementando el método abstracto.
Para terminar se registra como subclase de la clase abstracta con el método register. Con esto hacemos que la sentencia issubclass(some_var, AbstracFoo) devuelva True.
Como hemos visto, para que se considere subclase de la clase abstracta la clase concreta debe registrarse como subclase. Pero, ¿que pasa si queremos que cualquier otra clase sea considerada subclase de la abstracta y no la hemos registrado como subclase?
Para este problema tenemos el método __subclasshook__, que personalizará el comportamiento de issubclass sin necesidad de tener que invocar a register previamente. Este método debe devolver True, False o NotImplemented.
Muy buena entrada Jesús, práctica y concisa.
ResponderEliminarTe cuento que también llevo a delante un blog y hace un tiempo también escribí sobre clases en python.
Seguire tus avances!!!
Saludos, Diego
Muy buenas, aunque algo leo algo tarde el comentario añado tu blog a marcadores.
EliminarUn saludo!!