2

ABC classes are created to check object type and as such they cannot be instantiated. In fact:

basestring()

throws:

TypeError: The basestring type cannot be instantiated

However, this does not happen for the ABC number:

from numbers import number

number()

it does not throw any exceptions. Whereas other ABCs from the same module do:

from numbers import Real
from numbers import Complex

Real()  # or Complex()

throws:

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__

Why is that ?

kalehmann
  • 4,821
  • 6
  • 26
  • 36
Harry C.
  • 41
  • 1
  • 4

1 Answers1

1

A look at the source for the numbers module provides the answer:

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

As you can see, the numbers.Number class has abc.ABCMeta as metaclass. And since it has no methods decorated with @ab.cabstractmethod, @abc.abstractclassmethod or @abc.abstractstaticmethod the abc.ABCMeta class does not prevent the instanciation.

The classes numbers.Real and numbers.Complex on the other hand inherit from numbers.Number and decorate many methods with @abc.abstractmethod, therefore they cannot be instanciated.

That means numbers.Number is most likely only instanciable because of the way abstract classes work in Python and not because someone specifically build it to be so.

kalehmann
  • 4,821
  • 6
  • 26
  • 36