2017-06-15 5 views
8

Supposons que j'ai une classe de base avec des méthodes non implémentées comme suit:force classe enfant à remplacer les méthodes de parents

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

    def perimeter(self): 
     pass 

    def area(self): 
     pass 

Maintenant, disons que l'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?

Répondre

16

cela pourrait être votre classe parent:

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

    def perimeter(self): 
     raise NotImplementedError 

    def area(self): 
     raise NotImplementedError 

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


une version différente est d'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 2 * math.pi * self.radius 


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 qu'il ait toutes les méthodes mises en œuvre. Il s'agit de la syntaxe python 3; en python 2 vous aurez besoin de

class Polygon(object): 
    __metaclass__ = ABCMeta 

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

2

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

class Polygon: 
    def area(self): 
     raise NotImplementedError 

vous pouvez également utiliser @abc.abstractmethod, mais vous devez déclarer métaclasse être abc.ABCMeta, ce qui rendrait votre classe abstraite. En savoir plus sur abc module

2

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

Dans votre classe de base