Les méthodes abstraites du module abc de python ne font aucune distinction entre les classes et les instances.

python n'avait pas de classe ou d'interface abstraite. Cependant, avec l'ajout du module abc (abréviation de la classe de base abstraite), il est devenu possible d'y parvenir en utilisant des décorateurs. Cette fois, expérimentons pour découvrir les conditions dans lesquelles la classe abstraite donne réellement une erreur.

La classe abstraite donne une erreur lors de la création d'une instance

Les classes abstraites appliquent les fonctions (méthodes) que vous souhaitez qu'elles implémentent. Si vous ne l'implémentez pas en python, vous n'obtiendrez une erreur que lorsque vous instanciez une classe implémentée (plus précisément, une classe non implémentée). Par conséquent, même une classe qui n'implémente pas de méthode abstraite ne provoquera pas d'erreur si elle est uniquement accessible pour utiliser la méthode de classe. Dans les cas suivants, l'erreur se produit uniquement lors de l'instanciation de la classe abstraite et de ses sous-classes.

from abc import *

class Abstract(object, metaclass=ABCMeta):

    @classmethod
    @abstractmethod
    def hello(cls):
        print("Abstract hello")

class Implement(Abstract):
    pass

Abstract.hello()
# => Abstract hello
Implement.hello()
# => Abstract hello

# Abstract()
# TypeError: Can't instantiate abstract class Abstract with abstract methods hello

# Implement()
# TypeError: Can't instantiate abstract class Implement with abstract methods hello

Bien sûr, lors de l'instanciation, vous devez implémenter (définir) une méthode abstraite. Même si vous créez une autre méthode, elle n'est pas reconnue comme implémentée. En d'autres termes, il ne répond pas aux critères du créateur de la classe abstraite. Vérifions-le.

from abc import *

class Abstract(object, metaclass=ABCMeta):

    @classmethod
    @abstractmethod
    def hello(cls):
        print("Abstract hello")

class Implement(Abstract):
    @classmethod
    def say(cls):
        print("Implement class-method say")

    def yeah(self):
        print("Implement instance-method yeah")

Implement()

# => TypeError: Can't instantiate abstract class Implement with abstract methods hello

Aucune distinction n'est faite entre les méthodes de classe abstraites et les méthodes d'instance

Définissez une méthode de classe d'une classe abstraite en tant que méthode abstraite. Si vous définissez une méthode portant le même nom qu'une méthode d'instance dans cette sous-classe, aucune erreur ne se produira. Peut-être que python est tous des objets et indiscernable, donc il ne détermine que le nom, pas le type de méthode.

from abc import *

class Abstract(object, metaclass=ABCMeta):

    @classmethod
    @abstractmethod
    def hello(cls):
        print("Abstract hello")

class Implement(Abstract):
    def hello(self):
        print("Implement hello")

impl = Implement()
impl.hello()

# => Implement hello

Définissons une méthode de classe abstraite comme méthode d'instance et une méthode d'instance abstraite comme méthode de classe. L'erreur cette fois est due à l'absence de la méthode de classe bonjour. Étant donné que la sous-classe hello est une instance et que la classe parente hello est une méthode abstraite, la méthode de classe entraînera une erreur car hello n'est pas implémentée. Cela ne cause pas d'erreur pour accéder à la classe, mais cela dit que c'est inutile car il n'y a aucune méthode pour l'utiliser.

from abc import *

class Abstract(object, metaclass=ABCMeta):

    @classmethod
    @abstractmethod
    def hello(cls):
        print("Abstract hello")

    def say(self):
        print("Abstract say")

class Implement(Abstract):

    def hello(self):
        print("Implement hello")

    @classmethod
    def say(cls):
        print("Implement say")

impl = Implement()
impl.hello()
impl.say()
# =>
# Implement hello
# Implement say

# Implement.hello()
# hello() missing 1 required positional argument: 'self'

Implement.say()

# =>
# Implement say

Jusqu'où pouvez-vous forcer la mise en œuvre

Dans cette expérience, nous avons constaté qu'il n'est pas possible de faire la distinction entre les méthodes de classe et les méthodes d'instance. Vous avez peut-être préparé l'erreur vous-même ou vous avez peut-être une méthode dans les options du module abc. Mais gardez à l'esprit que l'utilisation normale ne peut que limiter l'implémentation de méthodes portant le même nom.

Recommended Posts

Les méthodes abstraites du module abc de python ne font aucune distinction entre les classes et les instances.
Classes et instances Python, méthodes d'instance
Lier des méthodes aux classes et instances Python
Résumé des différences entre PHP et Python
La réponse de "1/2" est différente entre python2 et 3
Prise en compte de la différence entre la courbe ROC et la courbe PR
[python] Récupère la liste des classes définies dans le module
Visualisation de la connexion entre le malware et le serveur de rappel