PEP 3119 утверждает, что:Почему @abstractmethod необходимо использовать в классе, чей метакласс получен из ABCMeta?
@abstractmethod
декоратора следует использовать только внутри тела класса, и только для классов, метакласс (полученный из)ABCMeta
. Динамическое добавление абстрактных методов в класс или попытка изменить статус абстракции метода или класса после его создания не поддерживаются.
Я не могу найти, однако, объяснение, почему это так. В частности, я не замечаю разницы в поведении при использовании только @abstractmethod
в классе, который явно не наследуется от ABCMeta
. В следующем простом примере, если я правильно понимаю, правильный способ делать вещи будет:
import six
from abc import ABCMeta
from abc import abstractmethod
class Base(six.with_metaclass(ABCMeta)):
def __init__(self):
print('Init abstract base')
@abstractmethod
def do_something(self):
pass
class Subclass(Base):
def __init__(self):
super(Subclass, self).__init__()
def do_something(self):
print('Done.')
sub = Subclass()
sub.do_something()
Однако, если я позволяю Base
класса унаследованы просто из object
, и использовать только декоратор, когда это необходимо, я замечаю, никаких изменений в поведении.
from abc import abstractmethod
class Base(object):
def __init__(self):
print('Init abstract base')
@abstractmethod
def do_something(self):
pass
class Subclass(Base):
def __init__(self):
super(Subclass, self).__init__()
def do_something(self):
print('Done.')
sub = Subclass()
sub.do_something()
Я нашел это место даже на более сложных архитектур, поэтому я задаюсь вопросом: когда же последний способ потерпеть неудачу?