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?
cela pourrait être votre classe parente:
class Polygon():
def __init__(self):
raise NotImplementedError
def perimeter(self):
raise NotImplementedError
def area(self):
raise NotImplementedError
bien que le problème ne soit détecté qu'au moment de l'exécution, lorsqu'une des instances des classes enfant tente d'appeler l'une de ces méthodes.
une version différente doit utiliser abc.abstractmethod
.
from abc import ABCMeta, abstractmethod
# simpler alternative: from abc import ABC, abstractmethod
import math
class Polygon(metaclass=ABCMeta):
# simpler alternative: class Polygon(ABC)
@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 pourrez pas instancier un Circle
sans que toutes les méthodes soient implémentées.
c'est la syntaxe python 3
; dans python 2
vous auriez besoin de
class Polygon(object):
__metaclass__ = ABCMeta
notez également que pour les fonctions spéciales binaires __eq__(), __lt__(), __add__(), ...
, il est préférable de return NotImplemented
au lieu de relever NotImplementedError
.
C'est exactement à quoi servent NotImplementedError
:)
Dans votre classe de base
def area(self):
raise NotImplementedError("Hey, Don't forget to implement the area!")
Vous pouvez lever NotImplementedError
exception dans la méthode de la classe de base.
class Polygon:
def area(self):
raise NotImplementedError
Aussi, vous pouvez utiliser @abc.abstractmethod
, mais vous devez ensuite déclarer la métaclasse comme abc.ABCMeta
, ce qui rendrait votre classe abstraite. En savoir plus sur abc
module