Поскольку этот вопрос был задан изначально, python изменил способ реализации абстрактных классов. Я использовал немного другой подход с использованием формализма abc.ABC в Python 3.6. Здесь я определяю константу как свойство, которое должно быть определено в каждом подклассе.
from abc import ABC, abstractmethod
class Base(ABC):
@property
@classmethod
@abstractmethod
def CONSTANT(cls):
return NotImplementedError
def print_constant(self):
print(type(self).CONSTANT)
class Derived(Base):
CONSTANT = 42
Это заставляет производный класс определять константу, иначе возникнет исключение TypeError
, когда вы попытаетесь создать экземпляр подкласса. Если вы хотите использовать константу для любой функциональности, реализованной в абстрактном классе, вы должны получить доступ к константе подкласса по type(self).CONSTANT
вместо просто CONSTANT
, поскольку значение в базовом классе не определено.
Есть и другие способы реализации этого, но мне нравится этот синтаксис, так как он кажется мне наиболее простым и очевидным для читателя.
Все предыдущие ответы касались полезных моментов, но я считаю, что принятый ответ не дает прямого ответа на вопрос, потому что
- Вопрос требует реализации в абстрактном классе, но принятый ответ не следует за абстрактным формализмом.
- Вопрос требует, чтобы реализация была принудительной. Я бы сказал, что в этом ответе соблюдение более строгое, поскольку оно вызывает ошибку времени выполнения, когда создается экземпляр подкласса, если
CONSTANT
не определен. Принятый ответ позволяет создать экземпляр объекта и выдает ошибку только при обращении к CONSTANT
, что делает применение менее строгим.
Это не вина оригинальных ответов. Со времени их публикации произошли серьезные изменения в синтаксисе абстрактного класса, что в данном случае позволяет более аккуратную и функциональную реализацию.