[2] | 1 | # Copyright 2007 Google, Inc. All Rights Reserved.
|
---|
| 2 | # Licensed to PSF under a Contributor Agreement.
|
---|
| 3 |
|
---|
| 4 | """Abstract Base Classes (ABCs) for numbers, according to PEP 3141.
|
---|
| 5 |
|
---|
| 6 | TODO: Fill out more detailed documentation on the operators."""
|
---|
| 7 |
|
---|
| 8 | from __future__ import division
|
---|
| 9 | from abc import ABCMeta, abstractmethod, abstractproperty
|
---|
| 10 |
|
---|
| 11 | __all__ = ["Number", "Complex", "Real", "Rational", "Integral"]
|
---|
| 12 |
|
---|
| 13 | class Number(object):
|
---|
| 14 | """All numbers inherit from this class.
|
---|
| 15 |
|
---|
| 16 | If you just want to check if an argument x is a number, without
|
---|
| 17 | caring what kind, use isinstance(x, Number).
|
---|
| 18 | """
|
---|
| 19 | __metaclass__ = ABCMeta
|
---|
| 20 | __slots__ = ()
|
---|
| 21 |
|
---|
| 22 | # Concrete numeric types must provide their own hash implementation
|
---|
| 23 | __hash__ = None
|
---|
| 24 |
|
---|
| 25 |
|
---|
| 26 | ## Notes on Decimal
|
---|
| 27 | ## ----------------
|
---|
| 28 | ## Decimal has all of the methods specified by the Real abc, but it should
|
---|
| 29 | ## not be registered as a Real because decimals do not interoperate with
|
---|
| 30 | ## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But,
|
---|
| 31 | ## abstract reals are expected to interoperate (i.e. R1 + R2 should be
|
---|
| 32 | ## expected to work if R1 and R2 are both Reals).
|
---|
| 33 |
|
---|
| 34 | class Complex(Number):
|
---|
| 35 | """Complex defines the operations that work on the builtin complex type.
|
---|
| 36 |
|
---|
| 37 | In short, those are: a conversion to complex, .real, .imag, +, -,
|
---|
| 38 | *, /, abs(), .conjugate, ==, and !=.
|
---|
| 39 |
|
---|
| 40 | If it is given heterogenous arguments, and doesn't have special
|
---|
| 41 | knowledge about them, it should fall back to the builtin complex
|
---|
| 42 | type as described below.
|
---|
| 43 | """
|
---|
| 44 |
|
---|
| 45 | __slots__ = ()
|
---|
| 46 |
|
---|
| 47 | @abstractmethod
|
---|
| 48 | def __complex__(self):
|
---|
| 49 | """Return a builtin complex instance. Called for complex(self)."""
|
---|
| 50 |
|
---|
| 51 | # Will be __bool__ in 3.0.
|
---|
| 52 | def __nonzero__(self):
|
---|
| 53 | """True if self != 0. Called for bool(self)."""
|
---|
| 54 | return self != 0
|
---|
| 55 |
|
---|
| 56 | @abstractproperty
|
---|
| 57 | def real(self):
|
---|
| 58 | """Retrieve the real component of this number.
|
---|
| 59 |
|
---|
| 60 | This should subclass Real.
|
---|
| 61 | """
|
---|
| 62 | raise NotImplementedError
|
---|
| 63 |
|
---|
| 64 | @abstractproperty
|
---|
| 65 | def imag(self):
|
---|
[391] | 66 | """Retrieve the imaginary component of this number.
|
---|
[2] | 67 |
|
---|
| 68 | This should subclass Real.
|
---|
| 69 | """
|
---|
| 70 | raise NotImplementedError
|
---|
| 71 |
|
---|
| 72 | @abstractmethod
|
---|
| 73 | def __add__(self, other):
|
---|
| 74 | """self + other"""
|
---|
| 75 | raise NotImplementedError
|
---|
| 76 |
|
---|
| 77 | @abstractmethod
|
---|
| 78 | def __radd__(self, other):
|
---|
| 79 | """other + self"""
|
---|
| 80 | raise NotImplementedError
|
---|
| 81 |
|
---|
| 82 | @abstractmethod
|
---|
| 83 | def __neg__(self):
|
---|
| 84 | """-self"""
|
---|
| 85 | raise NotImplementedError
|
---|
| 86 |
|
---|
| 87 | @abstractmethod
|
---|
| 88 | def __pos__(self):
|
---|
| 89 | """+self"""
|
---|
| 90 | raise NotImplementedError
|
---|
| 91 |
|
---|
| 92 | def __sub__(self, other):
|
---|
| 93 | """self - other"""
|
---|
| 94 | return self + -other
|
---|
| 95 |
|
---|
| 96 | def __rsub__(self, other):
|
---|
| 97 | """other - self"""
|
---|
| 98 | return -self + other
|
---|
| 99 |
|
---|
| 100 | @abstractmethod
|
---|
| 101 | def __mul__(self, other):
|
---|
| 102 | """self * other"""
|
---|
| 103 | raise NotImplementedError
|
---|
| 104 |
|
---|
| 105 | @abstractmethod
|
---|
| 106 | def __rmul__(self, other):
|
---|
| 107 | """other * self"""
|
---|
| 108 | raise NotImplementedError
|
---|
| 109 |
|
---|
| 110 | @abstractmethod
|
---|
| 111 | def __div__(self, other):
|
---|
| 112 | """self / other without __future__ division
|
---|
| 113 |
|
---|
| 114 | May promote to float.
|
---|
| 115 | """
|
---|
| 116 | raise NotImplementedError
|
---|
| 117 |
|
---|
| 118 | @abstractmethod
|
---|
| 119 | def __rdiv__(self, other):
|
---|
| 120 | """other / self without __future__ division"""
|
---|
| 121 | raise NotImplementedError
|
---|
| 122 |
|
---|
| 123 | @abstractmethod
|
---|
| 124 | def __truediv__(self, other):
|
---|
| 125 | """self / other with __future__ division.
|
---|
| 126 |
|
---|
| 127 | Should promote to float when necessary.
|
---|
| 128 | """
|
---|
| 129 | raise NotImplementedError
|
---|
| 130 |
|
---|
| 131 | @abstractmethod
|
---|
| 132 | def __rtruediv__(self, other):
|
---|
| 133 | """other / self with __future__ division"""
|
---|
| 134 | raise NotImplementedError
|
---|
| 135 |
|
---|
| 136 | @abstractmethod
|
---|
| 137 | def __pow__(self, exponent):
|
---|
| 138 | """self**exponent; should promote to float or complex when necessary."""
|
---|
| 139 | raise NotImplementedError
|
---|
| 140 |
|
---|
| 141 | @abstractmethod
|
---|
| 142 | def __rpow__(self, base):
|
---|
| 143 | """base ** self"""
|
---|
| 144 | raise NotImplementedError
|
---|
| 145 |
|
---|
| 146 | @abstractmethod
|
---|
| 147 | def __abs__(self):
|
---|
| 148 | """Returns the Real distance from 0. Called for abs(self)."""
|
---|
| 149 | raise NotImplementedError
|
---|
| 150 |
|
---|
| 151 | @abstractmethod
|
---|
| 152 | def conjugate(self):
|
---|
| 153 | """(x+y*i).conjugate() returns (x-y*i)."""
|
---|
| 154 | raise NotImplementedError
|
---|
| 155 |
|
---|
| 156 | @abstractmethod
|
---|
| 157 | def __eq__(self, other):
|
---|
| 158 | """self == other"""
|
---|
| 159 | raise NotImplementedError
|
---|
| 160 |
|
---|
| 161 | def __ne__(self, other):
|
---|
| 162 | """self != other"""
|
---|
| 163 | # The default __ne__ doesn't negate __eq__ until 3.0.
|
---|
| 164 | return not (self == other)
|
---|
| 165 |
|
---|
| 166 | Complex.register(complex)
|
---|
| 167 |
|
---|
| 168 |
|
---|
| 169 | class Real(Complex):
|
---|
| 170 | """To Complex, Real adds the operations that work on real numbers.
|
---|
| 171 |
|
---|
| 172 | In short, those are: a conversion to float, trunc(), divmod,
|
---|
| 173 | %, <, <=, >, and >=.
|
---|
| 174 |
|
---|
| 175 | Real also provides defaults for the derived operations.
|
---|
| 176 | """
|
---|
| 177 |
|
---|
| 178 | __slots__ = ()
|
---|
| 179 |
|
---|
| 180 | @abstractmethod
|
---|
| 181 | def __float__(self):
|
---|
| 182 | """Any Real can be converted to a native float object.
|
---|
| 183 |
|
---|
| 184 | Called for float(self)."""
|
---|
| 185 | raise NotImplementedError
|
---|
| 186 |
|
---|
| 187 | @abstractmethod
|
---|
| 188 | def __trunc__(self):
|
---|
| 189 | """trunc(self): Truncates self to an Integral.
|
---|
| 190 |
|
---|
| 191 | Returns an Integral i such that:
|
---|
| 192 | * i>0 iff self>0;
|
---|
| 193 | * abs(i) <= abs(self);
|
---|
| 194 | * for any Integral j satisfying the first two conditions,
|
---|
| 195 | abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
|
---|
| 196 | i.e. "truncate towards 0".
|
---|
| 197 | """
|
---|
| 198 | raise NotImplementedError
|
---|
| 199 |
|
---|
| 200 | def __divmod__(self, other):
|
---|
| 201 | """divmod(self, other): The pair (self // other, self % other).
|
---|
| 202 |
|
---|
| 203 | Sometimes this can be computed faster than the pair of
|
---|
| 204 | operations.
|
---|
| 205 | """
|
---|
| 206 | return (self // other, self % other)
|
---|
| 207 |
|
---|
| 208 | def __rdivmod__(self, other):
|
---|
| 209 | """divmod(other, self): The pair (self // other, self % other).
|
---|
| 210 |
|
---|
| 211 | Sometimes this can be computed faster than the pair of
|
---|
| 212 | operations.
|
---|
| 213 | """
|
---|
| 214 | return (other // self, other % self)
|
---|
| 215 |
|
---|
| 216 | @abstractmethod
|
---|
| 217 | def __floordiv__(self, other):
|
---|
| 218 | """self // other: The floor() of self/other."""
|
---|
| 219 | raise NotImplementedError
|
---|
| 220 |
|
---|
| 221 | @abstractmethod
|
---|
| 222 | def __rfloordiv__(self, other):
|
---|
| 223 | """other // self: The floor() of other/self."""
|
---|
| 224 | raise NotImplementedError
|
---|
| 225 |
|
---|
| 226 | @abstractmethod
|
---|
| 227 | def __mod__(self, other):
|
---|
| 228 | """self % other"""
|
---|
| 229 | raise NotImplementedError
|
---|
| 230 |
|
---|
| 231 | @abstractmethod
|
---|
| 232 | def __rmod__(self, other):
|
---|
| 233 | """other % self"""
|
---|
| 234 | raise NotImplementedError
|
---|
| 235 |
|
---|
| 236 | @abstractmethod
|
---|
| 237 | def __lt__(self, other):
|
---|
| 238 | """self < other
|
---|
| 239 |
|
---|
| 240 | < on Reals defines a total ordering, except perhaps for NaN."""
|
---|
| 241 | raise NotImplementedError
|
---|
| 242 |
|
---|
| 243 | @abstractmethod
|
---|
| 244 | def __le__(self, other):
|
---|
| 245 | """self <= other"""
|
---|
| 246 | raise NotImplementedError
|
---|
| 247 |
|
---|
| 248 | # Concrete implementations of Complex abstract methods.
|
---|
| 249 | def __complex__(self):
|
---|
| 250 | """complex(self) == complex(float(self), 0)"""
|
---|
| 251 | return complex(float(self))
|
---|
| 252 |
|
---|
| 253 | @property
|
---|
| 254 | def real(self):
|
---|
| 255 | """Real numbers are their real component."""
|
---|
| 256 | return +self
|
---|
| 257 |
|
---|
| 258 | @property
|
---|
| 259 | def imag(self):
|
---|
| 260 | """Real numbers have no imaginary component."""
|
---|
| 261 | return 0
|
---|
| 262 |
|
---|
| 263 | def conjugate(self):
|
---|
| 264 | """Conjugate is a no-op for Reals."""
|
---|
| 265 | return +self
|
---|
| 266 |
|
---|
| 267 | Real.register(float)
|
---|
| 268 |
|
---|
| 269 |
|
---|
| 270 | class Rational(Real):
|
---|
| 271 | """.numerator and .denominator should be in lowest terms."""
|
---|
| 272 |
|
---|
| 273 | __slots__ = ()
|
---|
| 274 |
|
---|
| 275 | @abstractproperty
|
---|
| 276 | def numerator(self):
|
---|
| 277 | raise NotImplementedError
|
---|
| 278 |
|
---|
| 279 | @abstractproperty
|
---|
| 280 | def denominator(self):
|
---|
| 281 | raise NotImplementedError
|
---|
| 282 |
|
---|
| 283 | # Concrete implementation of Real's conversion to float.
|
---|
| 284 | def __float__(self):
|
---|
| 285 | """float(self) = self.numerator / self.denominator
|
---|
| 286 |
|
---|
| 287 | It's important that this conversion use the integer's "true"
|
---|
| 288 | division rather than casting one side to float before dividing
|
---|
| 289 | so that ratios of huge integers convert without overflowing.
|
---|
| 290 |
|
---|
| 291 | """
|
---|
| 292 | return self.numerator / self.denominator
|
---|
| 293 |
|
---|
| 294 |
|
---|
| 295 | class Integral(Rational):
|
---|
| 296 | """Integral adds a conversion to long and the bit-string operations."""
|
---|
| 297 |
|
---|
| 298 | __slots__ = ()
|
---|
| 299 |
|
---|
| 300 | @abstractmethod
|
---|
| 301 | def __long__(self):
|
---|
| 302 | """long(self)"""
|
---|
| 303 | raise NotImplementedError
|
---|
| 304 |
|
---|
| 305 | def __index__(self):
|
---|
[391] | 306 | """Called whenever an index is needed, such as in slicing"""
|
---|
[2] | 307 | return long(self)
|
---|
| 308 |
|
---|
| 309 | @abstractmethod
|
---|
| 310 | def __pow__(self, exponent, modulus=None):
|
---|
| 311 | """self ** exponent % modulus, but maybe faster.
|
---|
| 312 |
|
---|
| 313 | Accept the modulus argument if you want to support the
|
---|
| 314 | 3-argument version of pow(). Raise a TypeError if exponent < 0
|
---|
| 315 | or any argument isn't Integral. Otherwise, just implement the
|
---|
| 316 | 2-argument version described in Complex.
|
---|
| 317 | """
|
---|
| 318 | raise NotImplementedError
|
---|
| 319 |
|
---|
| 320 | @abstractmethod
|
---|
| 321 | def __lshift__(self, other):
|
---|
| 322 | """self << other"""
|
---|
| 323 | raise NotImplementedError
|
---|
| 324 |
|
---|
| 325 | @abstractmethod
|
---|
| 326 | def __rlshift__(self, other):
|
---|
| 327 | """other << self"""
|
---|
| 328 | raise NotImplementedError
|
---|
| 329 |
|
---|
| 330 | @abstractmethod
|
---|
| 331 | def __rshift__(self, other):
|
---|
| 332 | """self >> other"""
|
---|
| 333 | raise NotImplementedError
|
---|
| 334 |
|
---|
| 335 | @abstractmethod
|
---|
| 336 | def __rrshift__(self, other):
|
---|
| 337 | """other >> self"""
|
---|
| 338 | raise NotImplementedError
|
---|
| 339 |
|
---|
| 340 | @abstractmethod
|
---|
| 341 | def __and__(self, other):
|
---|
| 342 | """self & other"""
|
---|
| 343 | raise NotImplementedError
|
---|
| 344 |
|
---|
| 345 | @abstractmethod
|
---|
| 346 | def __rand__(self, other):
|
---|
| 347 | """other & self"""
|
---|
| 348 | raise NotImplementedError
|
---|
| 349 |
|
---|
| 350 | @abstractmethod
|
---|
| 351 | def __xor__(self, other):
|
---|
| 352 | """self ^ other"""
|
---|
| 353 | raise NotImplementedError
|
---|
| 354 |
|
---|
| 355 | @abstractmethod
|
---|
| 356 | def __rxor__(self, other):
|
---|
| 357 | """other ^ self"""
|
---|
| 358 | raise NotImplementedError
|
---|
| 359 |
|
---|
| 360 | @abstractmethod
|
---|
| 361 | def __or__(self, other):
|
---|
| 362 | """self | other"""
|
---|
| 363 | raise NotImplementedError
|
---|
| 364 |
|
---|
| 365 | @abstractmethod
|
---|
| 366 | def __ror__(self, other):
|
---|
| 367 | """other | self"""
|
---|
| 368 | raise NotImplementedError
|
---|
| 369 |
|
---|
| 370 | @abstractmethod
|
---|
| 371 | def __invert__(self):
|
---|
| 372 | """~self"""
|
---|
| 373 | raise NotImplementedError
|
---|
| 374 |
|
---|
| 375 | # Concrete implementations of Rational and Real abstract methods.
|
---|
| 376 | def __float__(self):
|
---|
| 377 | """float(self) == float(long(self))"""
|
---|
| 378 | return float(long(self))
|
---|
| 379 |
|
---|
| 380 | @property
|
---|
| 381 | def numerator(self):
|
---|
| 382 | """Integers are their own numerators."""
|
---|
| 383 | return +self
|
---|
| 384 |
|
---|
| 385 | @property
|
---|
| 386 | def denominator(self):
|
---|
| 387 | """Integers have a denominator of 1."""
|
---|
| 388 | return 1
|
---|
| 389 |
|
---|
| 390 | Integral.register(int)
|
---|
| 391 | Integral.register(long)
|
---|