您的位置:  首页 » Python » numbers-数字抽象基类详解(1)Python语言的数学和数学模块(必读进阶学习教程)(参考资料)

numbers模块(PEP 3141)定义了数字抽象基类的层次结构 ,逐步定义更多操作。此模块中定义的所有类型都不能实例化。

numbers.Number
数字层次结构的根。如果你只是想检查一个参数 x是一个数字,而不关心什么类型,请使用。isinstance(x,Number)

数字塔

numbers.Complex
此类型的子类描述复数,并包括对内置complex类型起作用的操作。它们是:转换到 complexboolrealimag+, -*/abs()conjugate()==,和!=。所有除外-并且!=都是抽象的。

real
抽象。检索此数字的实际组件。
imag
抽象。检索此数字的虚部。
abstractmethod conjugate
抽象。返回复共轭。例如,。(1+3j).conjugate() == (1-3j)
numbers.Real
To ComplexReal添加了对实数进行处理的操作。

总之,这些是:一次转化floatmath.trunc(), round()math.floor()math.ceil()divmod()//%<<=>,和>=

真正还提供了默认值complex()real, imag,和conjugate()

numbers.Rational
子类型Real和添加 numeratordenominator属性,应该是最低的。有了这些,它提供了默认值 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。我将参考上面没有引用的所有代码MyIntegralOtherTypeIKnowAbout“样板文件”。a将是一个实例A,它是Complex()的子类型,和。我会考虑:a : A <:Complexb : B <: Complexa + b

  1. 如果A定义了一个__add__()接受b,一切都很好。
  2. 如果A回退到样板代码,并且它返回一个值__add__(),我们就会错过B定义更智能的可能性__radd__(),因此样板应该NotImplemented从中 返回__add__()。(或者A可能根本没有实施__add__()。)
  3. 随后B__radd__()得到一个机会。如果它接受 a,一切都很好。
  4. 如果它回退到样板文件中,则没有更多可能的方法可以尝试,因此这是默认实现应该存在的地方。
  5. 如果,Python尝试过 。这是可以的,因为它是在知道的情况下实现的,所以它可以在委托之前处理这些实例。B <: AB.__radd__A.__add__AComplex

如果和不共享任何其他知识,那么适当的共享操作是涉及内置的操作,并且两者都在那里着陆,所以。A <:ComplexB <: Realcomplex__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)

# ...

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注