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