3.3.8. 模拟数字类型

定义以下方法即可模拟数字类型。特定种类的数字不支持的运算(例如非整数不能进行位运算)所对应的方法应当保持未定义状态。

  • object.add(self, other)
  • object.sub(self, other)
  • object.mul(self, other)
  • object.matmul(self, other)
  • object.truediv(self, other)
  • object.floordiv(self, other)
  • object.mod(self, other)
  • object.divmod(self, other)
  • object.pow(self, other[, modulo])
  • object.lshift(self, other)
  • object.rshift(self, other)
  • object.and(self, other)
  • object.xor(self, other)
  • object.or(self, other)
  • 调用这些方法来实现二进制算术运算 (+, -, , @, /, //, %, divmod(), pow(), *, <<, >>, &, ^, |)。例如,求表达式 x + y 的值,其中 x 是具有 add() 方法的类的一个实例,则会调用 x.add(y)divmod() 方法应该等价于使用 floordiv()mod(),它不应该被关联到 truediv()。请注意如果要支持三元版本的内置 pow() 函数,则 pow() 的定义应该接受可选的第三个参数。

如果这些方法中的某一个不支持与所提供参数进行运算,它应该返回 NotImplemented

  • object.radd(self, other)
  • object.rsub(self, other)
  • object.rmul(self, other)
  • object.rmatmul(self, other)
  • object.rtruediv(self, other)
  • object.rfloordiv(self, other)
  • object.rmod(self, other)
  • object.rdivmod(self, other)
  • object.rpow(self, other)
  • object.rlshift(self, other)
  • object.rrshift(self, other)
  • object.rand(self, other)
  • object.rxor(self, other)
  • object.ror(self, other)
  • 调用这些方法来实现具有反射(交换)操作数的二进制算术运算 (+, -, , @, /, //, %, divmod(), pow(), *, <<, >>, &, ^, |)。这些成员函数仅会在左操作数不支持相应运算 3 且两个操作数类型不同时被调用。4 例如,求表达式 x - y 的值,其中 y 是具有 rsub() 方法的类的一个实例,则当 x.sub(y) 返回 NotImplemented 时会调用 y.rsub(x)

请注意三元版的 pow() 并不会尝试调用 rpow() (因为强制转换规则会太过复杂)。

注解

如果右操作数类型为左操作数类型的一个子类,且该子类提供了指定运算的反射方法,则此方法会先于左操作数的非反射方法被调用。此行为可允许子类重载其祖先类的运算符。

  • object.iadd(self, other)
  • object.isub(self, other)
  • object.imul(self, other)
  • object.imatmul(self, other)
  • object.itruediv(self, other)
  • object.ifloordiv(self, other)
  • object.imod(self, other)
  • object.ipow(self, other[, modulo])
  • object.ilshift(self, other)
  • object.irshift(self, other)
  • object.iand(self, other)
  • object.ixor(self, other)
  • object.ior(self, other)
  • 调用这些方法来实现扩展算术赋值 (+=, -=, =, @=, /=, //=, %=, *=, <<=, >>=, &=, ^=, |=)。这些方法应该尝试进行自身操作 (修改 self) 并返回结果 (结果应该但并非必须为 self)。如果某个方法未被定义,相应的扩展算术赋值将回退到普通方法。例如,如果 x 是具有 iadd() 方法的类的一个实例,则 x += y 就等价于 x = x.iadd(y)。否则就如 x + y 的求值一样选择 x.add(y)y.radd(x)。在某些情况下,扩展赋值可导致未预期的错误 (参见 为什么 a_tuple[i] += ['item'] 会在执行加法时引发异常?),但此行为实际上是数据模型的一个组成部分。
  • object.neg(self)
  • object.pos(self)
  • object.abs(self)
  • object.invert(self)
  • 调用此方法以实现一元算术运算 (-, +, abs()~)。
  • object.complex(self)
  • object.int(self)
  • object.float(self)
  • 调用这些方法以实现内置函数 complex(), int()float()。应当返回一个相应类型的值。
  • object.index(self)
  • 调用此方法以实现 operator.index() 以及 Python 需要无损地将数字对象转换为整数对象的场合(例如切片或是内置的 bin(), hex()oct() 函数)。 存在此方法表明数字对象属于整数类型。 必须返回一个整数。

注解

为了具有一致的整数类型类,当定义了 index() 的时候也应当定义 int(),两者应当返回相同的值。

  • object.round(self[, ndigits])
  • object.trunc(self)
  • object.floor(self)
  • object.ceil(self)
  • 调用这些方法以实现内置函数 round() 以及 math 函数 trunc(), floor()ceil()。 除了将 ndigits 传给 round() 的情况之外这些方法的返回值都应当是原对象截断为 Integral (通常为 int)。

如果未定义 int() 则内置函数 int() 会回退到 trunc()