Предположим, что вы пишете абстрактный класс, и один или несколько его не-абстрактных методов класса требуют, чтобы конкретный класс имел определенный атрибут класса; например, если экземпляры каждого конкретного класса могут быть построены путем сопоставления с другим регулярным выражением, вы можете указать своей ABC следующее:
@classmethod
def parse(cls, s):
m = re.fullmatch(cls.PATTERN, s)
if not m:
raise ValueError(s)
return cls(**m.groupdict())
(Возможно, это может быть лучше реализовано с помощью пользовательского метакласса, но попробуйте проигнорировать это для примера.)
Теперь, поскольку переопределение абстрактных методов и свойств проверяется на время создания экземпляра, а не на время создания подкласса, пытаясь использовать abc.abstractmethod
, чтобы гарантировать, что конкретные классы имеют атрибуты PATTERN
, не будут работать - но, конечно, должно быть что-то чтобы рассказать кому-то, кто смотрит на ваш код "Я не забыл определить PATTERN
на ABC, конкретные классы должны определять их собственные". Возникает вопрос: что-то самое питоническое?
-
Куча декораторов
@property @abc.abstractmethod def PATTERN(self): pass
(Предположим, например, Python 3.4 или новее). Это может очень ввести в заблуждение читателей, так как это означает, что
PATTERN
должно быть свойством экземпляра, а не атрибутом класса. -
Башня декораторов
@property @classmethod @abc.abstractmethod def PATTERN(cls): pass
Это может быть очень запутанным для читателей, поскольку
@property
и@classmethod
обычно не могут комбинироваться; они работают только здесь (для заданного значения "работа" ), потому что метод игнорируется после переопределения. -
Значение фиктивного
PATTERN = ''
Если конкретный класс не может определить свой собственный
PATTERN
,parse
будет принимать только пустой ввод. Этот параметр не является широко применимым, поскольку не все варианты использования будут иметь соответствующее фиктивное значение. -
Ошибка, вызывающая фиктивное значение
PATTERN = None
Если конкретный класс не может определить свой собственный
PATTERN
,parse
вызовет ошибку, и программист получит то, что заслуживает. -
Ничего не делать. В принципе, более хардкорный вариант # 4. В ABC docstring может быть записка где-то, но сама ABC не должна иметь ничего похожего на атрибут
PATTERN
. -
Другое???