Принудительный класс для переопределения родительских методов

Предположим, что у меня есть базовый класс с нереализованными методами:

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

    def perimeter(self):
        pass

    def area(self):
        pass

Теперь скажем, что один из моих коллег использует класс Polygon для создания подкласса следующим образом:

import math

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

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

(H/Sh) e забыл реализовать метод area().

Как заставить подкласс реализовать метод parent area()?

Ответ 1

это может быть ваш родительский класс:

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

    def perimeter(self):
        raise NotImplementedError

    def area(self):
        raise NotImplementedError

хотя проблема будет обнаружена только во время выполнения, когда один из экземпляров дочерних классов пытается вызвать один из этих методов.


другая версия должна использовать 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

вы не сможете создать экземпляр Circle без реализации всех методов.

это синтаксис python 3; в python 2 вам нужно

class Polygon(object):
    __metaclass__ = ABCMeta

Также обратите внимание, что для двоичных специальных функций __eq__(), __lt__(), __add__(), ... лучше return NotImplemented вместо повышения NotImplementedError.

Ответ 2

Это именно то, для чего NotImplementedError используются :)

В вашем базовом классе

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

Ответ 3

Вы можете поднять NotImplementedError исключение в методе базового класса.

class Polygon:
    def area(self):
        raise NotImplementedError

Также вы можете использовать @abc.abstractmethod, но тогда вам нужно объявить метакласс для abc.ABCMeta, что сделает ваш класс абстрактным. Подробнее о abc module