首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

numbers

2.6版本中的新功能。

所述numbers模块(PEP 3141)定义的数值的层次抽象基类,其渐进地限定多个操作。本模块中定义的任何类型都不能实例化。

class numbers.Number

数字层次结构的根。如果你只是想检查一个参数x是否是一个数字,而不关心什么样的话,那就使用isinstance(x, Number)

数字塔

class numbers.Complex

这种类型的子类描述了复数,并包含了对内建complex类型起作用的操作。它们是:转换到complexboolrealimag+-*/abs()conjugate()==,和!=。所有除了-!=是抽象的。

real

抽象。检索此数字的实际组成部分。

imag

抽象。检索这个数字的虚部。

conjugate()

抽象。返回复共轭。例如,(1+3j).conjugate() == (1-3j)

class numbers.Real

ComplexReal增加了对实数起作用的操作。

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

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

class numbers.Rational

子类型Real和增加numeratordenominator属性,应该是最低的。有了这些,它提供了一个默认值float()

numerator

抽象。

denominator

抽象。

class numbers.Integral

子类型Rational并向其添加转换int。提供了默认值float()numeratordenominator。增加了对抽象方法**和比特字符串操作:<<>>&^|~

2.类型实现者的注释

实现者应该小心地使相等的数字相等并将它们散列为相同的值。如果有两个不同的实数扩展名,这可能很微妙。例如,fractions.Fraction实现hash()如下:

代码语言:javascript
复制
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

代码语言:javascript
复制
class MyFoo(Complex): ...
MyFoo.register(Real)

2.2。实现算术运算

我们希望实现算术运算,以便混合模式操作或者调用作者知道两个参数类型的实现,或者将两者都转换为最接近的内置类型并在那里执行操作。对于子类型Integral,这意味着__add__()__radd__()应该定义为:

代码语言:javascript
复制
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,它是Complexa : A <: Complex),和的子类型b : B <: Complex。我会考虑a + b

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

如果A <: ComplexB <: Real没有分享任何其他知识,那么适当的共享操作就是内置的操作complex,并且两者都__radd__()在那里,所以a+b == b+a

因为任何给定类型的大多数操作都非常相似,所以定义一个辅助函数会很有用,它可以生成任何给定操作符的正向和反向实例。例如,fractions.Fraction使用:

代码语言:javascript
复制
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)

# ...

扫码关注腾讯云开发者

领取腾讯云代金券