Python Language Impostazione del metaclass ABCMeta


Esempio

Le classi astratte sono classi che devono essere ereditate ma evitare l'implementazione di metodi specifici, lasciando solo le firme dei metodi che le sottoclassi devono implementare.

Le classi astratte sono utili per definire e applicare le astrazioni di classe ad un livello elevato, simile al concetto di interfacce nei linguaggi tipizzati, senza la necessità di implementazione del metodo.

Un approccio concettuale alla definizione di una classe astratta consiste nello stub dei metodi di classe, quindi genera un NotImplementedError se vi si accede. Questo impedisce alle classi di bambini di accedere ai metodi padre senza sovrascriverli prima. Così:

class Fruit:
    
    def check_ripeness(self):
        raise NotImplementedError("check_ripeness method not implemented!")


class Apple(Fruit):
    pass


a = Apple()
a.check_ripeness() # raises NotImplementedError

La creazione di una classe astratta in questo modo impedisce l'uso improprio di metodi che non sono sovrascritti, e certamente incoraggia i metodi da definire nelle classi figlie, ma non impone la loro definizione. Con il modulo abc possiamo impedire l'istanziazione delle classi figlie quando non riescono a scavalcare i metodi astratti di classe dei loro genitori e antenati:

from abc import ABCMeta

class AbstractClass(object):
    # the metaclass attribute must always be set as a class variable 
    __metaclass__ = ABCMeta

   # the abstractmethod decorator registers this method as undefined
   @abstractmethod 
   def virtual_method_subclasses_must_define(self):
       # Can be left completely blank, or a base implementation can be provided
       # Note that ordinarily a blank interpretation implicitly returns `None`, 
       # but by registering, this behaviour is no longer enforced.

Ora è possibile semplicemente eseguire la sottoclasse e l'override:

class Subclass(AbstractClass):
    def virtual_method_subclasses_must_define(self):
        return