blob: 1b594952ead7241dacf8fa751bd3e7a014ba15a4 [file] [log] [blame]
Christian Heimes072c0f12008-01-03 23:01:04 +00001:mod:`numbers` --- Numeric abstract base classes
2================================================
3
4.. module:: numbers
5 :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.).
6
Terry Jan Reedyfa089b92016-06-11 15:02:54 -04007**Source code:** :source:`Lib/numbers.py`
8
9--------------
Christian Heimesfaf2f632008-01-06 16:59:19 +000010
Éric Araujofa088db2011-06-04 18:42:38 +020011The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric
12:term:`abstract base classes <abstract base class>` which progressively define
13more operations. None of the types defined in this module can be instantiated.
Christian Heimes072c0f12008-01-03 23:01:04 +000014
15
16.. class:: Number
17
18 The root of the numeric hierarchy. If you just want to check if an argument
19 *x* is a number, without caring what kind, use ``isinstance(x, Number)``.
20
21
Christian Heimes072c0f12008-01-03 23:01:04 +000022The numeric tower
23-----------------
24
25.. class:: Complex
26
27 Subclasses of this type describe complex numbers and include the operations
Georg Brandlc5605df2009-08-13 08:26:44 +000028 that work on the built-in :class:`complex` type. These are: conversions to
Christian Heimes072c0f12008-01-03 23:01:04 +000029 :class:`complex` and :class:`bool`, :attr:`.real`, :attr:`.imag`, ``+``,
30 ``-``, ``*``, ``/``, :func:`abs`, :meth:`conjugate`, ``==``, and ``!=``. All
31 except ``-`` and ``!=`` are abstract.
32
Benjamin Petersone41251e2008-04-25 01:59:09 +000033 .. attribute:: real
Christian Heimes072c0f12008-01-03 23:01:04 +000034
Mark Dickinsonbc5f75c2010-05-05 21:55:11 +000035 Abstract. Retrieves the real component of this number.
Christian Heimes072c0f12008-01-03 23:01:04 +000036
Benjamin Petersone41251e2008-04-25 01:59:09 +000037 .. attribute:: imag
Christian Heimes072c0f12008-01-03 23:01:04 +000038
Mark Dickinsonbc5f75c2010-05-05 21:55:11 +000039 Abstract. Retrieves the imaginary component of this number.
Christian Heimes072c0f12008-01-03 23:01:04 +000040
Berker Peksag6e9d2e62015-12-08 12:14:50 +020041 .. abstractmethod:: conjugate()
Christian Heimes072c0f12008-01-03 23:01:04 +000042
Benjamin Petersone41251e2008-04-25 01:59:09 +000043 Abstract. Returns the complex conjugate. For example, ``(1+3j).conjugate()
44 == (1-3j)``.
Christian Heimes072c0f12008-01-03 23:01:04 +000045
46.. class:: Real
47
48 To :class:`Complex`, :class:`Real` adds the operations that work on real
49 numbers.
50
Benjamin Petersonab2b7162011-03-12 11:58:15 -060051 In short, those are: a conversion to :class:`float`, :func:`math.trunc`,
Christian Heimes072c0f12008-01-03 23:01:04 +000052 :func:`round`, :func:`math.floor`, :func:`math.ceil`, :func:`divmod`, ``//``,
53 ``%``, ``<``, ``<=``, ``>``, and ``>=``.
54
Georg Brandl1f01deb2009-01-03 22:47:39 +000055 Real also provides defaults for :func:`complex`, :attr:`~Complex.real`,
56 :attr:`~Complex.imag`, and :meth:`~Complex.conjugate`.
Christian Heimes072c0f12008-01-03 23:01:04 +000057
58
59.. class:: Rational
60
Christian Heimesf75b2902008-03-16 17:29:44 +000061 Subtypes :class:`Real` and adds
Georg Brandl1f01deb2009-01-03 22:47:39 +000062 :attr:`~Rational.numerator` and :attr:`~Rational.denominator` properties, which
Christian Heimes072c0f12008-01-03 23:01:04 +000063 should be in lowest terms. With these, it provides a default for
64 :func:`float`.
65
Benjamin Petersone41251e2008-04-25 01:59:09 +000066 .. attribute:: numerator
Christian Heimes072c0f12008-01-03 23:01:04 +000067
Benjamin Petersone41251e2008-04-25 01:59:09 +000068 Abstract.
Christian Heimes072c0f12008-01-03 23:01:04 +000069
Benjamin Petersone41251e2008-04-25 01:59:09 +000070 .. attribute:: denominator
Christian Heimes072c0f12008-01-03 23:01:04 +000071
Benjamin Petersone41251e2008-04-25 01:59:09 +000072 Abstract.
Christian Heimes072c0f12008-01-03 23:01:04 +000073
74
75.. class:: Integral
76
Georg Brandl1e1134a2013-04-14 11:58:54 +020077 Subtypes :class:`Rational` and adds a conversion to :class:`int`. Provides
78 defaults for :func:`float`, :attr:`~Rational.numerator`, and
79 :attr:`~Rational.denominator`. Adds abstract methods for ``**`` and
80 bit-string operations: ``<<``, ``>>``, ``&``, ``^``, ``|``, ``~``.
Christian Heimes7b3ce6a2008-01-31 14:31:45 +000081
82
83Notes for type implementors
84---------------------------
85
86Implementors should be careful to make equal numbers equal and hash
87them to the same values. This may be subtle if there are two different
Christian Heimes3feef612008-02-11 06:19:17 +000088extensions of the real numbers. For example, :class:`fractions.Fraction`
Christian Heimes7b3ce6a2008-01-31 14:31:45 +000089implements :func:`hash` as follows::
90
91 def __hash__(self):
92 if self.denominator == 1:
93 # Get integers right.
94 return hash(self.numerator)
95 # Expensive check, but definitely correct.
96 if self == float(self):
97 return hash(float(self))
98 else:
99 # Use tuple's hash to avoid a high collision rate on
100 # simple fractions.
101 return hash((self.numerator, self.denominator))
102
103
104Adding More Numeric ABCs
105~~~~~~~~~~~~~~~~~~~~~~~~
106
107There are, of course, more possible ABCs for numbers, and this would
108be a poor hierarchy if it precluded the possibility of adding
109those. You can add ``MyFoo`` between :class:`Complex` and
110:class:`Real` with::
111
112 class MyFoo(Complex): ...
113 MyFoo.register(Real)
114
115
Ethan Furmanb0049432014-11-26 21:15:35 -0800116.. _implementing-the-arithmetic-operations:
117
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000118Implementing the arithmetic operations
119~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120
121We want to implement the arithmetic operations so that mixed-mode
122operations either call an implementation whose author knew about the
123types of both arguments, or convert both to the nearest built in type
124and do the operation there. For subtypes of :class:`Integral`, this
125means that :meth:`__add__` and :meth:`__radd__` should be defined as::
126
127 class MyIntegral(Integral):
128
129 def __add__(self, other):
130 if isinstance(other, MyIntegral):
131 return do_my_adding_stuff(self, other)
132 elif isinstance(other, OtherTypeIKnowAbout):
133 return do_my_other_adding_stuff(self, other)
134 else:
135 return NotImplemented
136
137 def __radd__(self, other):
138 if isinstance(other, MyIntegral):
139 return do_my_adding_stuff(other, self)
140 elif isinstance(other, OtherTypeIKnowAbout):
141 return do_my_other_adding_stuff(other, self)
142 elif isinstance(other, Integral):
143 return int(other) + int(self)
144 elif isinstance(other, Real):
145 return float(other) + float(self)
146 elif isinstance(other, Complex):
147 return complex(other) + complex(self)
148 else:
149 return NotImplemented
150
151
152There are 5 different cases for a mixed-type operation on subclasses
153of :class:`Complex`. I'll refer to all of the above code that doesn't
154refer to ``MyIntegral`` and ``OtherTypeIKnowAbout`` as
155"boilerplate". ``a`` will be an instance of ``A``, which is a subtype
156of :class:`Complex` (``a : A <: Complex``), and ``b : B <:
157Complex``. I'll consider ``a + b``:
158
159 1. If ``A`` defines an :meth:`__add__` which accepts ``b``, all is
160 well.
161 2. If ``A`` falls back to the boilerplate code, and it were to
162 return a value from :meth:`__add__`, we'd miss the possibility
163 that ``B`` defines a more intelligent :meth:`__radd__`, so the
164 boilerplate should return :const:`NotImplemented` from
165 :meth:`__add__`. (Or ``A`` may not implement :meth:`__add__` at
166 all.)
167 3. Then ``B``'s :meth:`__radd__` gets a chance. If it accepts
168 ``a``, all is well.
169 4. If it falls back to the boilerplate, there are no more possible
170 methods to try, so this is where the default implementation
171 should live.
172 5. If ``B <: A``, Python tries ``B.__radd__`` before
173 ``A.__add__``. This is ok, because it was implemented with
174 knowledge of ``A``, so it can handle those instances before
175 delegating to :class:`Complex`.
176
Georg Brandl1f01deb2009-01-03 22:47:39 +0000177If ``A <: Complex`` and ``B <: Real`` without sharing any other knowledge,
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000178then the appropriate shared operation is the one involving the built
179in :class:`complex`, and both :meth:`__radd__` s land there, so ``a+b
180== b+a``.
181
182Because most of the operations on any given type will be very similar,
183it can be useful to define a helper function which generates the
184forward and reverse instances of any given operator. For example,
Christian Heimes3feef612008-02-11 06:19:17 +0000185:class:`fractions.Fraction` uses::
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000186
187 def _operator_fallbacks(monomorphic_operator, fallback_operator):
188 def forward(a, b):
Amaury Forgeot d'Arc6a00b642008-06-17 20:38:00 +0000189 if isinstance(b, (int, Fraction)):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000190 return monomorphic_operator(a, b)
191 elif isinstance(b, float):
192 return fallback_operator(float(a), b)
193 elif isinstance(b, complex):
194 return fallback_operator(complex(a), b)
195 else:
196 return NotImplemented
197 forward.__name__ = '__' + fallback_operator.__name__ + '__'
198 forward.__doc__ = monomorphic_operator.__doc__
199
200 def reverse(b, a):
Christian Heimes3feef612008-02-11 06:19:17 +0000201 if isinstance(a, Rational):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000202 # Includes ints.
203 return monomorphic_operator(a, b)
204 elif isinstance(a, numbers.Real):
205 return fallback_operator(float(a), float(b))
206 elif isinstance(a, numbers.Complex):
207 return fallback_operator(complex(a), complex(b))
208 else:
209 return NotImplemented
210 reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
211 reverse.__doc__ = monomorphic_operator.__doc__
212
213 return forward, reverse
214
215 def _add(a, b):
216 """a + b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000217 return Fraction(a.numerator * b.denominator +
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000218 b.numerator * a.denominator,
219 a.denominator * b.denominator)
220
221 __add__, __radd__ = _operator_fallbacks(_add, operator.add)
222
Christian Heimesf75b2902008-03-16 17:29:44 +0000223 # ...