numbers-数字抽象基类详解(1)Python语言的数学和数学模块(必读进阶学习教程)(参考资料)
该numbers
模块(PEP 3141)定义了数字抽象基类的层次结构 ,逐步定义更多操作。此模块中定义的所有类型都不能实例化。
- 类
numbers.
Number
- 数字层次结构的根。如果你只是想检查一个参数 x是一个数字,而不关心什么类型,请使用。
isinstance(x,Number)
数字塔
- 类
numbers.
Complex
- 此类型的子类描述复数,并包括对内置
complex
类型起作用的操作。它们是:转换到complex
和bool
,real
,imag
,+
,-
,*
,/
,abs()
,conjugate()
,==
,和!=
。所有除外-
并且!=
都是抽象的。real
- 抽象。检索此数字的实际组件。
imag
- 抽象。检索此数字的虚部。
- abstractmethod
conjugate
() - 抽象。返回复共轭。例如,。
(1+3j).conjugate() == (1-3j)
- 类
numbers.
Real
- To
Complex
,Real
添加了对实数进行处理的操作。总之,这些是:一次转化
float
,math.trunc()
,round()
,math.floor()
,math.ceil()
,divmod()
,//
,%
,<
,<=
,>
,和>=
。真正还提供了默认值
complex()
,real
,imag
,和conjugate()
。
- 类
numbers.
Rational
- 子类型
Real
和添加numerator
和denominator
属性,应该是最低的。有了这些,它提供了默认值float()
。numerator
- 抽象。
denominator
- 抽象。
- 类
numbers.
Integral
- 子类型
Rational
并添加转换int
。提供了默认值float()
,numerator
和denominator
。增加了对抽象方法**
和比特字符串操作:<<
,>>
,&
,^
,|
,~
。
类型实现者的注释
实现者应该小心地使相等的数字相等并将它们哈希到相同的值。如果实数有两个不同的扩展,这可能是微妙的。例如,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))
添加更多的数字基本知识
当然,对于数字,有更多可能的ABC,如果它排除了添加这些的可能性,那么这将是一个糟糕的层次结构。您可以添加MyFoo
之间Complex
,并 Real
搭配:
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
对于子类的混合类型操作有5种不同的情况Complex
。我将参考上面没有引用的所有代码MyIntegral
和OtherTypeIKnowAbout
“样板文件”。a
将是一个实例A
,它是Complex
()的子类型,和。我会考虑:a : A <:Complex
b : B <: Complex
a + b
- 如果
A
定义了一个__add__()
接受b
,一切都很好。- 如果
A
回退到样板代码,并且它返回一个值__add__()
,我们就会错过B
定义更智能的可能性__radd__()
,因此样板应该NotImplemented
从中 返回__add__()
。(或者A
可能根本没有实施__add__()
。)- 随后
B
的__radd__()
得到一个机会。如果它接受a
,一切都很好。- 如果它回退到样板文件中,则没有更多可能的方法可以尝试,因此这是默认实现应该存在的地方。
- 如果,Python尝试过 。这是可以的,因为它是在知道的情况下实现的,所以它可以在委托之前处理这些实例。
B <: A
B.__radd__
A.__add__
A
Complex
如果和不共享任何其他知识,那么适当的共享操作是涉及内置的操作,并且两者都在那里着陆,所以。A <:Complex
B <: Real
complex
__radd__()
a+b == b+a
因为任何给定类型的大多数操作都非常相似,所以定义一个生成任何给定运算符的正向和反向实例的辅助函数会很有用。例如, 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) # ...
本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如果侵犯你的利益,请发送邮箱到 [email protected],我们会很快的为您处理。