Python 中文开发手册
numbers (Numeric & Mathematical) - Python 中文开发手册
2.6版本中的新功能。
所述numbers模块(PEP 3141)定义的数值的层次抽象基类,其渐进地限定多个操作。本模块中定义的任何类型都不能实例化。
class numbers.Number
数字层次结构的根。如果你只是想检查一个参数x是否是一个数字,而不关心什么样的话,那就使用isinstance(x, Number)。
数字塔
class numbers.Complex
这种类型的子类描述了复数,并包含了对内建complex类型起作用的操作。它们是:转换到complex和bool,real,imag,+,-,*,/,abs(),conjugate(),==,和!=。所有除了-和!=是抽象的。
real
抽象。检索此数字的实际组成部分。
imag
抽象。检索这个数字的虚部。
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
抽象。
class numbers.Integral
子类型Rational并向其添加转换int。提供了默认值float(),numerator和denominator。增加了对抽象方法**和比特字符串操作:<>,&,^,|,~。
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))
2.1。添加更多数字ABCs
当然,对于数字来说,有更多可能的ABC,如果它排除了添加这些数字的可能性,这将是一个糟糕的等级。你可以添加和MyFoo之间:ComplexReal
class MyFoo(Complex): ...
MyFoo.register(Real)
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
对于子类的混合类型操作有5种不同的情况Complex。我将参考上述所有没有提及的代码,MyIntegral并将其OtherTypeIKnowAbout作为“样板”。a将是一个实例A,它是Complex(a : A <: complex : b>
如果A定义一个__add__()接受b,一切都很好。如果A退回到样板代码,并从中返回一个值__add__(),我们会错过B定义更智能的可能性__radd__(),所以样板应该NotImplemented从中返回__add__()。(或者A可能根本没有实施__add__()。)随后B的__radd__()得到一个机会。如果它接受a,一切都很好。如果它回落到样板,则没有更多可能的方法来尝试,所以这是默认实现应该存在的地方。如果B <: a>
如果A <: complex real b>
因为任何给定类型的大多数操作都非常相似,所以定义一个辅助函数会很有用,它可以生成任何给定操作符的正向和反向实例。例如,fractions.Fraction使用:
def _operator_fallbacks(monomorphic_operator, fallback_operator):
def forward(a, b):
if isinstance(b, (int, long, 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)
# ...