"numbers" --- 數值的抽象基底類別
********************************

**原始碼：**Lib/numbers.py

======================================================================

"numbers" 模組 (**PEP 3141**) 定義了數值*抽象基底類別* 的階層結構，其
中逐一定義了更多操作。此模組中定義的型別都不可被實例化。

class numbers.Number

   數值階層結構的基礎。如果你只想確認引數 *x* 是不是數值、並不關心其型
   別，請使用 "isinstance(x, Number)"。


數值的階層
==========

class numbers.Complex

   這個型別的子類別描述了複數並包含適用於內建 "complex" 型別的操作。這
   些操作有："complex" 和 "bool" 的轉換、"real"、"imag"、"+"、"-"、"*"
   、"/"、"**"、"abs()"、"conjugate()"、"==" 以及 "!="。除 "-" 和 "!="
   之外所有操作都是抽象的。

   real

      為抽象的。取得該數值的實數部分。

   imag

      為抽象的。取得該數值的虛數部分。

   abstractmethod conjugate()

      為抽象的。回傳共軛複數，例如 "(1+3j).conjugate() == (1-3j)"。

class numbers.Real

   相對於 "Complex"，"Real" 加入了只有實數才能進行的操作。

   簡單的說，有 "float" 的轉換、"math.trunc()"、"round()"、
   "math.floor()"、"math.ceil()"、"divmod()"、"//"、"%"、 "<"、"<="、
   ">"、和 ">="。

   實數同樣提供 "complex()"、"real"、"imag" 和 "conjugate()" 的預設值
   。

class numbers.Rational

   "Real" 的子型別，並增加了 "numerator" 和 "denominator" 這兩種特性。
   它也會提供 "float()" 的預設值。

   "numerator" 和 "denominator" 的值必須是 "Integral" 的實例且
   "denominator" 要是正數。

   numerator

      為抽象的。該有理數的分子。

   denominator

      為抽象的。該有理數的分母。

class numbers.Integral

   "Rational" 的子型別，並增加了 "int" 的轉換操作。為 "float()"、
   "numerator" 和 "denominator" 提供了預設值。為 "pow()" 方法增加了求
   餘 (modulus) 和位元字串運算 (bit-string operations) 的抽象方法：
   "<<"、">>"、"&"、"^"、"|"、"~"。


給型別實作者的註記
==================

實作者需注意，相等的數值除了大小相等外，還必須擁有同樣的雜湊值。當使用
兩個不同的實數擴充時，這可能是很微妙的。例如，"fractions.Fraction" 底
下的 "hash()" 實作如下：

   def __hash__(self):
       if self.denominator == 1:
           # 正確處理整數。
           return hash(self.numerator)
       # 檢查費時，但絕對正確。
       if self == float(self):
           return hash(float(self))
       else:
           # 使用 tuple 的雜湊值以避免簡單分數上的高碰撞率。
           return hash((self.numerator, self.denominator))


加入更多數值 ABC
----------------

當然，還有更多用於數值的 ABC，如果不加入它們就不會有健全的階層。你可以
在 "Complex" 和 "Real" 中加入 "MyFoo"，像是：

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


實作算術操作
------------

我們想要實作算術操作，來使得混合模式操作要麼呼叫一個作者知道兩個引數之
型別的實作，要麼將其轉換成最接近的內建型別並執行這個操作。對於
"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" 的程式碼稱作「模板 (boilerplate)
」。"a" 是 "Complex" 之子型別 "A" 的實例 ("a : A <: Complex")，同時 "b
: B <: Complex"。我將要計算 "a + b"：

1. 如果 "A" 有定義成一個接受 "b" 的 "__add__()"，不會發生問題。

2. 如果 "A" 回退成模板程式碼，它將回傳一個來自 "__add__()" 的值，並喪
   失讓 "B" 定義一個更完善的 "__radd__()" 的機會，因此模板需要回傳一個
   來自 "__add__()" 的 "NotImplemented"。（或者 "A" 可能完全不實作
   "__add__()"。）

3. 接著看 "B" 的 "__radd__()"。如果它接受 "a" ，不會發生問題。

4. 如果沒有成功回退到模板，就沒有更多的方法可以去嘗試，因此這裡將使用
   預設的實作。

5. 如果 "B <: A"，Python 會在 "A.__add__" 之前嘗試 "B.__radd__"。這是
   可行的，因為它是透過對 "A" 的理解而實作的，所以這可以在交給
   "Complex" 之前處理好這些實例。

如果 "A <: Complex" 和 "B <: Real" 且沒有共享任何其他型別上的理解，那
麼適當的共享操作會涉及內建的 "complex"，並且分別用到 "__radd__()"，因
此 "a+b == b+a"。

由於大部分對任意給定類型的操作都十分相似的，定義一個為任意給定運算子生
成向前 (forward) 與向後 (reverse) 實例的輔助函式可能會非常有用。例如，
"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):
               # 包含整數。
               return monomorphic_operator(a, b)
           elif isinstance(a, Real):
               return fallback_operator(float(a), float(b))
           elif isinstance(a, 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)

   # ...
