Номер класса ABC из числового модуля - PullRequest
2 голосов
/ 22 июня 2019

ABC классы создаются для проверки типа объекта и, как таковые, они не могут быть созданы. На самом деле:

basestring()

кидает:

TypeError: The basestring type cannot be instantiated

Однако для номера ABC этого не происходит:

from numbers import number

number()

не исключает никаких исключений. Принимая во внимание, что другие ABC из того же модуля делают:

from numbers import Real
from numbers import Complex

Real()  # or Complex()

броски:

TypeError: Can't instantiate abstract class Real with abstract methods __abs__, __add__, __div__, __eq__, __float__, __floordiv__, __le__, __lt__, __mod__, __mul__, __neg__, __pos__, __pow__, __radd__, __rdiv__, __rfloordiv__, __rmod__, __rmul__, __rpow__, __rtruediv__, __truediv__, __trunc__

Почему это?

1 Ответ

1 голос
/ 23 июня 2019

Посмотрите на источник для модуля чисел дает ответ:

class Number(metaclass=ABCMeta):
    """All numbers inherit from this class.
    If you just want to check if an argument x is a number, without
    caring what kind, use isinstance(x, Number).
    """
    __slots__ = ()

    # Concrete numeric types must provide their own hash implementation
    __hash__ = None

Как видите, класс numbers.Number имеет abc.ABCMeta в качестве метакласса. И поскольку у него нет методов, декорированных @ab.cabstractmethod, @abc.abstractclassmethod или @abc.abstractstaticmethod, класс abc.ABCMeta не предотвращает создание экземпляров.

Классы numbers.Real и numbers.Complex, с другой стороны, наследуются от numbers.Number и украшают многие методы с помощью @abc.abstractmethod, поэтому они не могут быть созданы.

Это означает, что numbers.Number, скорее всего, может быть реализовано только из-за того, как абстрактные классы работают в Python, а не из-за того, что кто-то специально его так строит.

...