Python Language Pourquoi / Comment utiliser ABCMeta et @abstractmethod


Exemple

Les classes de base abstraites (ABC) imposent les classes dérivées qui implémentent des méthodes particulières de la classe de base.

Pour comprendre comment cela fonctionne et pourquoi nous devrions l’utiliser, jetons un coup d’œil à un exemple que Van Rossum apprécierait. Disons que nous avons une classe de base "MontyPython" avec deux méthodes (blague & ligne de frappe) qui doivent être implémentées par toutes les classes dérivées.

class MontyPython:
    def joke(self):
        raise NotImplementedError()

    def punchline(self):
        raise NotImplementedError()

class ArgumentClinic(MontyPython):
    def joke(self):
        return "Hahahahahah"

Lorsque nous instancions un objet et appelons deux méthodes, nous obtenons une erreur (comme prévu) avec la méthode punchline() .

 >>> sketch = ArgumentClinic() 
 >>> sketch.punchline() 
NotImplementedError 

Cependant, cela nous permet toujours d'instancier un objet de la classe ArgumentClinic sans obtenir d'erreur. En fait, nous n'obtenons pas d'erreur tant que nous ne cherchons pas la punchline ().

Ceci est évité en utilisant le module ABC (Abstract Base Class). Voyons comment cela fonctionne avec le même exemple:

from abc import ABCMeta, abstractmethod

class MontyPython(metaclass=ABCMeta):
    @abstractmethod
    def joke(self):
        pass

@abstractmethod
def punchline(self):
    pass

class ArgumentClinic(MontyPython):
    def joke(self):
        return "Hahahahahah"

Cette fois, lorsque nous essayons d’instancier un objet à partir de la classe incomplète, nous obtenons immédiatement une erreur TypeError!

>>> c = ArgumentClinic()
TypeError:
"Can't instantiate abstract class ArgumentClinic with abstract methods punchline"

Dans ce cas, il est facile de terminer la classe pour éviter tout type d’erreur:

class ArgumentClinic(MontyPython):
    def joke(self):
        return "Hahahahahah"

    def punchline(self):
        return "Send in the constable!"

Cette fois, lorsque vous instanciez un objet, cela fonctionne!