GeezerVison is showing python.github.io — numbers --- 數值的抽象基底類別 — Python 3.15.2 說明文件
numbers --- 數值的抽象基底類別¶
原始碼:Lib/numbers.py
numbers 模組 (PEP 3141) 定義了數值抽象基底類別 的階層結構,其中逐一定義了更多操作。此模組中定義的型別都不可被實例化。
-
class numbers.Number¶
數值階層結構的基礎。如果你只想確認引數 x 是不是數值、並不關心其型別,請使用 isinstance(x, Number)。
給型別實作者的註記¶
實作者應謹慎地讓相等的數值相等,並將它們雜湊為相同的值。若存在兩種不同的實數擴充,這可能會很微妙。另請參閱數值型別的雜湊。
Adding more numeric ABCs¶
當然,還有更多用於數值的 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
There are 5 different cases for a mixed-type operation on subclasses
of Complex. All of the above code that doesn't refer to
MyIntegral and OtherTypeIKnowAbout is referred to as "boilerplate".
In this description, a is an instance of A and b is an
instance of B, where A and B are both subtypes of Complex.
Consider a + b:
如果 A 有定義成一個接受 b 的 __add__(),不會發生問題。
如果 A 回退成模板程式碼,它將回傳一個來自 __add__() 的值,並喪失讓 B 定義一個更完善的 __radd__() 的機會,因此模板需要回傳一個來自 __add__() 的 NotImplemented。(或者 A 可能完全不實作 __add__()。)
接著看 B 的 __radd__()。如果它接受 a ,不會發生問題。
如果沒有成功回退到模板,就沒有更多的方法可以去嘗試,因此這裡將使用預設的實作。
If B is a subtype of 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 is a subtype of Complex and B is a subtype of
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.
由於大部分對任意給定類型的操作都十分相似的,定義一個為任意給定運算子生成向前 (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)
# ...
© 版權所有 2001 Python Software Foundation.
此頁面採用 Python 軟體基金會授權條款第 2 版。
文件中的範例、應用技巧與其他程式碼額外採用了 Zero Clause BSD 授權條款。
更多訊息請見 歷史與授權條款。
Python 軟體基金會是一家非營利法人。
敬請捐贈。
最後更新於 11月 11, 2026 (06:44 UTC)。
發現 bug?
以 Sphinx8.2.3建立。
|