abs

Модуль abc объявляет метакласс и пару декораторов, с помощью которых определяются новые абстрактные базовые классы.

ABCMeta()

class abs.ABCMeta

Метакласс, являющийся представлением абстрактного базового класса. Чтобы определить абстрактный базовый класс, необходимо объявить класс, использующий метакласс ABCMeta. Например:

import abc

class Stackable:
    __metaclass__ = abc.ABCMeta

Классы, созданные таким способом, имеют следующие важные отличия от обычных классов:

  • если в абстрактном классе объявляются методы или свойства с использованием декораторов @abstractmethod и @abstractproperty, то экземпляры производных классов не могут быть созданы, если эти классы не имеют неабстрактных реализаций этих методов и свойств.

  • абстрактные классы обладают методом класса register(subclass), который может использоваться для регистрации дополнительных типов как логических подклассов. Для любого подкласса, зарегистрированного с помощью этого метода, вызов isinstance(x, AbstractClass) будет возвращать True, если x является экземпляром этого подкласса.

  • абстрактные классы могут объявлять специальный метод класса __subclasshook__(cls, subclass). Этот метод должен возвращать True, если тип класса subclass может считаться подклассом класса cls, False – если класс subclass не является подклассом cls, или возбуждать исключение NotImplemented, если невозможно сделать никаких предположений о принадлежности класса subclass к иерархии.

abs.abstractmethod(method)

Декоратор, который объявляет метод method абстрактным. Когда этот декоратор используется в абстрактном базовом классе, классы, непосредственно объявленные как производные этого базового класса, могут использоваться для создания экземпляров, только если они включают неабстрактное определение метода method. Этот декоратор не оказывает влияния на подклассы, зарегистрированные с помощью метода register() абстрактного базового класса.

abs.abstractproperty(fget[, fset[, fdel[, doc]]])

Создает абстрактное свойство. Этот декоратор принимает те же аргументы, что и обычная функция property(). Когда этот декоратор используется в абстрактном базовом классе, классы, непосредственно объявленные как производные этого базового класса, могут использоваться для создания экземпляров, только если они включают неабстрактное определение свойства. В следующем фрагменте приводится пример объявления простого аб-

from abc import ABCMeta, abstractmethod, abstractproperty

class Stackable:

    __metaclass__ = ABCMeta # class Stackable(metaclass=ABCMeta)

    @abstractmethod
    def push(self,item):
        pass

    @abstractmethod
    def pop(self):
        pass

    @abstractproperty
    def size(self):
        pass

# класс, производный от класса Stackable
class Stack(Stackable):

    def __init__(self):
        self.items = []

    def push(self,item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

"""
сообщение об ошибке,
которое выводится при попытке создать экземпляр класса Stack:
s = Stack()
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
TypeError: Can’t instantiate abstract class Stack with abstract methods size

Чтобы исправить эту ошибку,
необходимо добавить определение свойства size() в класс Stack.
"""