# 9.1. `numbers` - 数字抽象基类

源代码： Lib/numbers.py

`numbers`模块（ PEP 3141）定义了逐渐定义更多操作的数字abstract base classes的层次结构。本模块中定义的任何类型，都不能被实例化。

class `numbers.``Number`

  数字层次结构的根。如果只想检查参数x是否为数字，而不考虑什么类型，请使用`isinstance（x， Number）` 。

## 9.1.1.The numeric tower

class `numbers.``Complex`

  此类型的子类描述复数，并包括对内建`complex`类型工作的操作。These are: conversions to `complex` and `bool`, `real`, `imag`, `+`, `-`, `*`, `/`, `abs()`, `conjugate()`, `==`, and `!=`. 除`-`和`!=`之外的都是抽象的。

  `real`

    抽象。检索此数的实部。

  `imag`

    抽象。检索此数的虚部。

  abstractmethod `conjugate`()

    抽象。返回共轭复数。例如，`（1 + 3j）.conjugate() == （1-3j）`。

class `numbers.``Real`

  到`Complex`，`Real`添加了对实数起作用的操作。

  In short, those are: a conversion to `float`, `math.trunc()`, `round()`, `math.floor()`, `math.ceil()`, `divmod()`, `//`, `%`, `<`, `<=`, `>`, and `>=`.

  Real还为`complex()`，`real`，`imag`和`conjugate()`提供默认值。

class `numbers.``Rational`

  子类型`Real`并添加`numerator`和`denominator`属性，这些属性应为最低值。有了这些，它提供了`float()`的默认值。

  `numerator`

    抽象。

  `denominator`

    抽象。

class `numbers.``Integral`

  子类型`Rational`，并向`int`添加转换。提供`float()`，`numerator`和`denominator`的默认值。Adds abstract methods for `**` and bit-string operations: `<<`, `>>`, `&`, `^`, `|`, `~`.

## 9.1.2.类型实现的注意事项

执行者要小心使相等的数字相等和散列他们为相同的值。这可能是实数的微妙的如果有两个不同的扩展。例如，`fractions.Fraction`实现`hash()`如下：

    def __hash__(self):
        if self.denominator == 1:
            # Get integers right.
            return hash(self.numerator)
        # Expensive check, but definitely correct.
        if self == float(self):
            return hash(float(self))
        else:
            # Use tuple's hash to avoid a high collision rate on
            # simple fractions.
            return hash((self.numerator, self.denominator))

### 9.1.2.1.添加更多数字ABCS

当然，有数字，更有可能基本要领，如果它排除了那些增加的可能性，这将是糟糕的层次结构。您可以在`Complex`和`Real`之间添加`MyFoo`：

    class MyFoo(Complex): ...
    MyFoo.register(Real)

### 9.1.2.2.实现算术运算

我们想要实现的算术运算，以便混合模式操作调用的作者知道这两个参数的类型的实现或都转换为最近内建类型和那里操作。对于子类型`Integral`，这意味着`__add__()`和`__radd__()`应定义为：

    class MyIntegral(Integral):

        def __add__(self, other):
            if isinstance(other, MyIntegral):
                return do_my_adding_stuff(self, other)
            elif isinstance(other, OtherTypeIKnowAbout):
                return do_my_other_adding_stuff(self, other)
            else:
                return NotImplemented

        def __radd__(self, other):
            if isinstance(other, MyIntegral):
                return do_my_adding_stuff(other, self)
            elif isinstance(other, OtherTypeIKnowAbout):
                return do_my_other_adding_stuff(other, self)
            elif isinstance(other, Integral):
                return int(other) + int(self)
            elif isinstance(other, Real):
                return float(other) + float(self)
            elif isinstance(other, Complex):
                return complex(other) + complex(self)
            else:
                return NotImplemented

对于`Complex`的子类的混合类型操作有5种不同的情况。我将引用所有上述代码，不将`MyIntegral`和`OtherTypeIKnowAbout`称为“样板”。`a` will be an instance of `A`, which is a subtype of `Complex` (`a : A <: Complex`), and `b : B <: Complex`. 我会考虑`a + b`：

> 1. If `A` defines an `__add__()` which accepts `b`, all is well.
> 2. If `A` falls back to the boilerplate code, and it were to return a value from `__add__()`, we’d miss the possibility that `B` defines a more intelligent `__radd__()`, so the boilerplate should return `NotImplemented` from `__add__()`. (Or `A` may not implement `__add__()` at all.)
> 3. Then `B`‘s `__radd__()` gets a chance. If it accepts `a`, all is well.
> 4. If it falls back to the boilerplate, there are no more possible methods to try, so this is where the default implementation should live.
> 5. If `B <: A`, Python tries `B.__radd__` before `A.__add__`. This is ok, because it was implemented with knowledge of `A`, so it can handle those instances before delegating to `Complex`.

If `A <: Complex` and `B <: Real` without sharing any other knowledge, then the appropriate shared operation is the one involving the built in `complex`, and both `__radd__()` s land there, so `a+b == b+a`.

由于大多数任何给定类型操作会很相似，因此，它能定义可生成任何给定操作正反向实例的 helper 函数。例如，`fractions.Fraction`使用：

    def _operator_fallbacks(monomorphic_operator, fallback_operator):
        def forward(a, b):
            if isinstance(b, (int, Fraction)):
                return monomorphic_operator(a, b)
            elif isinstance(b, float):
                return fallback_operator(float(a), b)
            elif isinstance(b, complex):
                return fallback_operator(complex(a), b)
            else:
                return NotImplemented
        forward.__name__ = '__' + fallback_operator.__name__ + '__'
        forward.__doc__ = monomorphic_operator.__doc__

        def reverse(b, a):
            if isinstance(a, Rational):
                # Includes ints.
                return monomorphic_operator(a, b)
            elif isinstance(a, numbers.Real):
                return fallback_operator(float(a), float(b))
            elif isinstance(a, numbers.Complex):
                return fallback_operator(complex(a), complex(b))
            else:
                return NotImplemented
        reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
        reverse.__doc__ = monomorphic_operator.__doc__

        return forward, reverse

    def _add(a, b):
        """a + b"""
        return Fraction(a.numerator * b.denominator +
                        b.numerator * a.denominator,
                        a.denominator * b.denominator)

    __add__, __radd__ = _operator_fallbacks(_add, operator.add)

    # ...