Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 1 | :mod:`numbers` --- Numeric abstract base classes |
| 2 | ================================================ |
| 3 | |
| 4 | .. module:: numbers |
| 5 | :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.). |
| 6 | |
Christian Heimes | faf2f63 | 2008-01-06 16:59:19 +0000 | [diff] [blame] | 7 | |
Éric Araujo | fa088db | 2011-06-04 18:42:38 +0200 | [diff] [blame] | 8 | The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric |
| 9 | :term:`abstract base classes <abstract base class>` which progressively define |
| 10 | more operations. None of the types defined in this module can be instantiated. |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 11 | |
| 12 | |
| 13 | .. class:: Number |
| 14 | |
| 15 | The root of the numeric hierarchy. If you just want to check if an argument |
| 16 | *x* is a number, without caring what kind, use ``isinstance(x, Number)``. |
| 17 | |
| 18 | |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 19 | The numeric tower |
| 20 | ----------------- |
| 21 | |
| 22 | .. class:: Complex |
| 23 | |
| 24 | Subclasses of this type describe complex numbers and include the operations |
Georg Brandl | c5605df | 2009-08-13 08:26:44 +0000 | [diff] [blame] | 25 | that work on the built-in :class:`complex` type. These are: conversions to |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 26 | :class:`complex` and :class:`bool`, :attr:`.real`, :attr:`.imag`, ``+``, |
| 27 | ``-``, ``*``, ``/``, :func:`abs`, :meth:`conjugate`, ``==``, and ``!=``. All |
| 28 | except ``-`` and ``!=`` are abstract. |
| 29 | |
Benjamin Peterson | e41251e | 2008-04-25 01:59:09 +0000 | [diff] [blame] | 30 | .. attribute:: real |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 31 | |
Mark Dickinson | bc5f75c | 2010-05-05 21:55:11 +0000 | [diff] [blame] | 32 | Abstract. Retrieves the real component of this number. |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 33 | |
Benjamin Peterson | e41251e | 2008-04-25 01:59:09 +0000 | [diff] [blame] | 34 | .. attribute:: imag |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 35 | |
Mark Dickinson | bc5f75c | 2010-05-05 21:55:11 +0000 | [diff] [blame] | 36 | Abstract. Retrieves the imaginary component of this number. |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 37 | |
Benjamin Peterson | e41251e | 2008-04-25 01:59:09 +0000 | [diff] [blame] | 38 | .. method:: conjugate() |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 39 | |
Benjamin Peterson | e41251e | 2008-04-25 01:59:09 +0000 | [diff] [blame] | 40 | Abstract. Returns the complex conjugate. For example, ``(1+3j).conjugate() |
| 41 | == (1-3j)``. |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 42 | |
| 43 | .. class:: Real |
| 44 | |
| 45 | To :class:`Complex`, :class:`Real` adds the operations that work on real |
| 46 | numbers. |
| 47 | |
Benjamin Peterson | ab2b716 | 2011-03-12 11:58:15 -0600 | [diff] [blame] | 48 | In short, those are: a conversion to :class:`float`, :func:`math.trunc`, |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 49 | :func:`round`, :func:`math.floor`, :func:`math.ceil`, :func:`divmod`, ``//``, |
| 50 | ``%``, ``<``, ``<=``, ``>``, and ``>=``. |
| 51 | |
Georg Brandl | 1f01deb | 2009-01-03 22:47:39 +0000 | [diff] [blame] | 52 | Real also provides defaults for :func:`complex`, :attr:`~Complex.real`, |
| 53 | :attr:`~Complex.imag`, and :meth:`~Complex.conjugate`. |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 54 | |
| 55 | |
| 56 | .. class:: Rational |
| 57 | |
Christian Heimes | f75b290 | 2008-03-16 17:29:44 +0000 | [diff] [blame] | 58 | Subtypes :class:`Real` and adds |
Georg Brandl | 1f01deb | 2009-01-03 22:47:39 +0000 | [diff] [blame] | 59 | :attr:`~Rational.numerator` and :attr:`~Rational.denominator` properties, which |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 60 | should be in lowest terms. With these, it provides a default for |
| 61 | :func:`float`. |
| 62 | |
Benjamin Peterson | e41251e | 2008-04-25 01:59:09 +0000 | [diff] [blame] | 63 | .. attribute:: numerator |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 64 | |
Benjamin Peterson | e41251e | 2008-04-25 01:59:09 +0000 | [diff] [blame] | 65 | Abstract. |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 66 | |
Benjamin Peterson | e41251e | 2008-04-25 01:59:09 +0000 | [diff] [blame] | 67 | .. attribute:: denominator |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 68 | |
Benjamin Peterson | e41251e | 2008-04-25 01:59:09 +0000 | [diff] [blame] | 69 | Abstract. |
Christian Heimes | 072c0f1 | 2008-01-03 23:01:04 +0000 | [diff] [blame] | 70 | |
| 71 | |
| 72 | .. class:: Integral |
| 73 | |
Georg Brandl | 1e1134a | 2013-04-14 11:58:54 +0200 | [diff] [blame] | 74 | Subtypes :class:`Rational` and adds a conversion to :class:`int`. Provides |
| 75 | defaults for :func:`float`, :attr:`~Rational.numerator`, and |
| 76 | :attr:`~Rational.denominator`. Adds abstract methods for ``**`` and |
| 77 | bit-string operations: ``<<``, ``>>``, ``&``, ``^``, ``|``, ``~``. |
Christian Heimes | 7b3ce6a | 2008-01-31 14:31:45 +0000 | [diff] [blame] | 78 | |
| 79 | |
| 80 | Notes for type implementors |
| 81 | --------------------------- |
| 82 | |
| 83 | Implementors should be careful to make equal numbers equal and hash |
| 84 | them to the same values. This may be subtle if there are two different |
Christian Heimes | 3feef61 | 2008-02-11 06:19:17 +0000 | [diff] [blame] | 85 | extensions of the real numbers. For example, :class:`fractions.Fraction` |
Christian Heimes | 7b3ce6a | 2008-01-31 14:31:45 +0000 | [diff] [blame] | 86 | implements :func:`hash` as follows:: |
| 87 | |
| 88 | def __hash__(self): |
| 89 | if self.denominator == 1: |
| 90 | # Get integers right. |
| 91 | return hash(self.numerator) |
| 92 | # Expensive check, but definitely correct. |
| 93 | if self == float(self): |
| 94 | return hash(float(self)) |
| 95 | else: |
| 96 | # Use tuple's hash to avoid a high collision rate on |
| 97 | # simple fractions. |
| 98 | return hash((self.numerator, self.denominator)) |
| 99 | |
| 100 | |
| 101 | Adding More Numeric ABCs |
| 102 | ~~~~~~~~~~~~~~~~~~~~~~~~ |
| 103 | |
| 104 | There are, of course, more possible ABCs for numbers, and this would |
| 105 | be a poor hierarchy if it precluded the possibility of adding |
| 106 | those. You can add ``MyFoo`` between :class:`Complex` and |
| 107 | :class:`Real` with:: |
| 108 | |
| 109 | class MyFoo(Complex): ... |
| 110 | MyFoo.register(Real) |
| 111 | |
| 112 | |
| 113 | Implementing the arithmetic operations |
| 114 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 115 | |
| 116 | We want to implement the arithmetic operations so that mixed-mode |
| 117 | operations either call an implementation whose author knew about the |
| 118 | types of both arguments, or convert both to the nearest built in type |
| 119 | and do the operation there. For subtypes of :class:`Integral`, this |
| 120 | means that :meth:`__add__` and :meth:`__radd__` should be defined as:: |
| 121 | |
| 122 | class MyIntegral(Integral): |
| 123 | |
| 124 | def __add__(self, other): |
| 125 | if isinstance(other, MyIntegral): |
| 126 | return do_my_adding_stuff(self, other) |
| 127 | elif isinstance(other, OtherTypeIKnowAbout): |
| 128 | return do_my_other_adding_stuff(self, other) |
| 129 | else: |
| 130 | return NotImplemented |
| 131 | |
| 132 | def __radd__(self, other): |
| 133 | if isinstance(other, MyIntegral): |
| 134 | return do_my_adding_stuff(other, self) |
| 135 | elif isinstance(other, OtherTypeIKnowAbout): |
| 136 | return do_my_other_adding_stuff(other, self) |
| 137 | elif isinstance(other, Integral): |
| 138 | return int(other) + int(self) |
| 139 | elif isinstance(other, Real): |
| 140 | return float(other) + float(self) |
| 141 | elif isinstance(other, Complex): |
| 142 | return complex(other) + complex(self) |
| 143 | else: |
| 144 | return NotImplemented |
| 145 | |
| 146 | |
| 147 | There are 5 different cases for a mixed-type operation on subclasses |
| 148 | of :class:`Complex`. I'll refer to all of the above code that doesn't |
| 149 | refer to ``MyIntegral`` and ``OtherTypeIKnowAbout`` as |
| 150 | "boilerplate". ``a`` will be an instance of ``A``, which is a subtype |
| 151 | of :class:`Complex` (``a : A <: Complex``), and ``b : B <: |
| 152 | Complex``. I'll consider ``a + b``: |
| 153 | |
| 154 | 1. If ``A`` defines an :meth:`__add__` which accepts ``b``, all is |
| 155 | well. |
| 156 | 2. If ``A`` falls back to the boilerplate code, and it were to |
| 157 | return a value from :meth:`__add__`, we'd miss the possibility |
| 158 | that ``B`` defines a more intelligent :meth:`__radd__`, so the |
| 159 | boilerplate should return :const:`NotImplemented` from |
| 160 | :meth:`__add__`. (Or ``A`` may not implement :meth:`__add__` at |
| 161 | all.) |
| 162 | 3. Then ``B``'s :meth:`__radd__` gets a chance. If it accepts |
| 163 | ``a``, all is well. |
| 164 | 4. If it falls back to the boilerplate, there are no more possible |
| 165 | methods to try, so this is where the default implementation |
| 166 | should live. |
| 167 | 5. If ``B <: A``, Python tries ``B.__radd__`` before |
| 168 | ``A.__add__``. This is ok, because it was implemented with |
| 169 | knowledge of ``A``, so it can handle those instances before |
| 170 | delegating to :class:`Complex`. |
| 171 | |
Georg Brandl | 1f01deb | 2009-01-03 22:47:39 +0000 | [diff] [blame] | 172 | If ``A <: Complex`` and ``B <: Real`` without sharing any other knowledge, |
Christian Heimes | 7b3ce6a | 2008-01-31 14:31:45 +0000 | [diff] [blame] | 173 | then the appropriate shared operation is the one involving the built |
| 174 | in :class:`complex`, and both :meth:`__radd__` s land there, so ``a+b |
| 175 | == b+a``. |
| 176 | |
| 177 | Because most of the operations on any given type will be very similar, |
| 178 | it can be useful to define a helper function which generates the |
| 179 | forward and reverse instances of any given operator. For example, |
Christian Heimes | 3feef61 | 2008-02-11 06:19:17 +0000 | [diff] [blame] | 180 | :class:`fractions.Fraction` uses:: |
Christian Heimes | 7b3ce6a | 2008-01-31 14:31:45 +0000 | [diff] [blame] | 181 | |
| 182 | def _operator_fallbacks(monomorphic_operator, fallback_operator): |
| 183 | def forward(a, b): |
Amaury Forgeot d'Arc | 6a00b64 | 2008-06-17 20:38:00 +0000 | [diff] [blame] | 184 | if isinstance(b, (int, Fraction)): |
Christian Heimes | 7b3ce6a | 2008-01-31 14:31:45 +0000 | [diff] [blame] | 185 | return monomorphic_operator(a, b) |
| 186 | elif isinstance(b, float): |
| 187 | return fallback_operator(float(a), b) |
| 188 | elif isinstance(b, complex): |
| 189 | return fallback_operator(complex(a), b) |
| 190 | else: |
| 191 | return NotImplemented |
| 192 | forward.__name__ = '__' + fallback_operator.__name__ + '__' |
| 193 | forward.__doc__ = monomorphic_operator.__doc__ |
| 194 | |
| 195 | def reverse(b, a): |
Christian Heimes | 3feef61 | 2008-02-11 06:19:17 +0000 | [diff] [blame] | 196 | if isinstance(a, Rational): |
Christian Heimes | 7b3ce6a | 2008-01-31 14:31:45 +0000 | [diff] [blame] | 197 | # Includes ints. |
| 198 | return monomorphic_operator(a, b) |
| 199 | elif isinstance(a, numbers.Real): |
| 200 | return fallback_operator(float(a), float(b)) |
| 201 | elif isinstance(a, numbers.Complex): |
| 202 | return fallback_operator(complex(a), complex(b)) |
| 203 | else: |
| 204 | return NotImplemented |
| 205 | reverse.__name__ = '__r' + fallback_operator.__name__ + '__' |
| 206 | reverse.__doc__ = monomorphic_operator.__doc__ |
| 207 | |
| 208 | return forward, reverse |
| 209 | |
| 210 | def _add(a, b): |
| 211 | """a + b""" |
Christian Heimes | 3feef61 | 2008-02-11 06:19:17 +0000 | [diff] [blame] | 212 | return Fraction(a.numerator * b.denominator + |
Christian Heimes | 7b3ce6a | 2008-01-31 14:31:45 +0000 | [diff] [blame] | 213 | b.numerator * a.denominator, |
| 214 | a.denominator * b.denominator) |
| 215 | |
| 216 | __add__, __radd__ = _operator_fallbacks(_add, operator.add) |
| 217 | |
Christian Heimes | f75b290 | 2008-03-16 17:29:44 +0000 | [diff] [blame] | 218 | # ... |