83 votes

Forcer la classe enfant à remplacer les méthodes du parent

Supposons que j'ai une classe de base avec des méthodes non implémentées comme suit:

 class Polygon():
    def __init__(self):
        pass

    def perimeter(self):
        pass

    def area(self):
        pass
 

Supposons maintenant qu'un de mes collègues utilise la classe Polygon pour créer une sous-classe comme suit:

 import math

class Circle(Polygon):
    def __init__(self, radius):
        self.radius = radius

    def perimeter(self):
        return 2 * math.pi * self.radius
 

(H / Sh) e a oublié d'implémenter la méthode area ().

Comment puis-je forcer la sous-classe à implémenter la méthode area () du parent?

151voto

hiro protagonist Points 1983

ce pourrait être votre parent de la classe:

class Polygon():
    def __init__(self):
        raise NotImplementedError

    def perimeter(self):
        raise NotImplementedError

    def area(self):
        raise NotImplementedError

bien que le problème sera repéré lors de l'exécution seulement, lorsque l'une des instances de l'enfant des classes tente d'appeler l'une de ces méthodes.


une autre version consiste à utiliser abc.abstractmethod.

from abc import ABCMeta, abstractmethod
import math

class Polygon(metaclass=ABCMeta):

    @abstractmethod
    def __init__(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

    @abstractmethod
    def area(self):
        pass

class Circle(Polygon):
    def __init__(self, radius):
        self.radius = radius

    def perimeter(self):
        return 2 * math.pi * self.radius

#    def area(self):
#        return math.pi * self.radius**2


c = Circle(9.0)
# TypeError: Can't instantiate abstract class Circle
#            with abstract methods area

vous ne serez pas en mesure d'instancier un Circle sans avoir tous les moyens mis en œuvre.

c'est l' python 3 de la syntaxe; en python 2 vous auriez besoin de

class Polygon(object):
    __metaclass__ = ABCMeta

notez également que, pour les binaires fonctions spéciales __eq__(), __lt__(), __add__(), ... il est préférable d' return NotImplemented , au lieu de lever NotImplementedError.

7voto

C'est exactement ce pour quoi NotImplementedError sont utilisés :)

Dans votre classe de base

 def area(self):
    raise NotImplementedError('Hey, Don't forget to implement the area!')
 

7voto

vishes_shell Points 10206

Vous pouvez élever NotImplementedError d'exception dans la méthode de classe de base.

class Polygon:
    def area(self):
        raise NotImplementedError

Aussi, vous pouvez utiliser @abc.abstractmethod, mais alors vous devez déclarer métaclasse être abc.ABCMeta, ce qui rendrait votre classe abstraite. Plus sur abc module

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X