2 Установка метакласса ABCMeta

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

Абстрактные классы полезны для определения и реализации абстракций классов на высоком уровне, аналогично концепции интерфейсов в типизированных языках, без необходимости реализации метода.

Один концептуальный подход к определению абстрактного класса состоит в том, чтобы заглушить методы класса, а затем вызвать NotImplementedError при обращении к нему. Это предотвращает доступ дочерних классов к родительским методам без их переопределения. Вот так:

 class Fruit:

    def check_ripeness(self):
        raise NotImplementedError("check_ripeness method not implemented!")


class Apple(Fruit):
    pass


a = Apple()
a.check_ripeness() # raises NotImplementedError


 

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

 from abc import ABCMeta

class AbstractClass(object):
    # the metaclass attribute must always be set as a class variable 
    __metaclass__ = ABCMeta

   # the abstractmethod decorator registers this method as undefined
   @abstractmethod 
   def virtual_method_subclasses_must_define(self):
       # Can be left completely blank, or a base implementation can be provided
       # Note that ordinarily a blank interpretation implicitly returns `None`, 
       # but by registering, this behaviour is no longer enforced.

 

Теперь можно просто создать подкласс и переопределить:

 class Subclass(AbstractClass):
    def virtual_method_subclasses_must_define(self):
        return