|
1 :mod:`numbers` --- Numeric abstract base classes |
|
2 ================================================ |
|
3 |
|
4 .. module:: numbers |
|
5 :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.). |
|
6 |
|
7 .. versionadded:: 2.6 |
|
8 |
|
9 |
|
10 The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric abstract |
|
11 base classes which progressively define more operations. None of the types |
|
12 defined in this module can be instantiated. |
|
13 |
|
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 |
|
21 The 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:: real |
|
33 |
|
34 Abstract. Retrieves the :class:`Real` component of this number. |
|
35 |
|
36 .. attribute:: imag |
|
37 |
|
38 Abstract. Retrieves the :class:`Real` component of this number. |
|
39 |
|
40 .. method:: 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 |
|
60 Subtypes :class:`Real` and adds |
|
61 :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:: numerator |
|
66 |
|
67 Abstract. |
|
68 |
|
69 .. attribute:: denominator |
|
70 |
|
71 Abstract. |
|
72 |
|
73 |
|
74 .. class:: Integral |
|
75 |
|
76 Subtypes :class:`Rational` and adds a conversion to :class:`int`. |
|
77 Provides defaults for :func:`float`, :attr:`Rational.numerator`, and |
|
78 :attr:`Rational.denominator`, and bit-string operations: ``<<``, |
|
79 ``>>``, ``&``, ``^``, ``|``, ``~``. |
|
80 |
|
81 |
|
82 Notes for type implementors |
|
83 --------------------------- |
|
84 |
|
85 Implementors should be careful to make equal numbers equal and hash |
|
86 them to the same values. This may be subtle if there are two different |
|
87 extensions of the real numbers. For example, :class:`fractions.Fraction` |
|
88 implements :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 |
|
103 Adding More Numeric ABCs |
|
104 ~~~~~~~~~~~~~~~~~~~~~~~~ |
|
105 |
|
106 There are, of course, more possible ABCs for numbers, and this would |
|
107 be a poor hierarchy if it precluded the possibility of adding |
|
108 those. You can add ``MyFoo`` between :class:`Complex` and |
|
109 :class:`Real` with:: |
|
110 |
|
111 class MyFoo(Complex): ... |
|
112 MyFoo.register(Real) |
|
113 |
|
114 |
|
115 Implementing the arithmetic operations |
|
116 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
117 |
|
118 We want to implement the arithmetic operations so that mixed-mode |
|
119 operations either call an implementation whose author knew about the |
|
120 types of both arguments, or convert both to the nearest built in type |
|
121 and do the operation there. For subtypes of :class:`Integral`, this |
|
122 means 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 |
|
149 There are 5 different cases for a mixed-type operation on subclasses |
|
150 of :class:`Complex`. I'll refer to all of the above code that doesn't |
|
151 refer to ``MyIntegral`` and ``OtherTypeIKnowAbout`` as |
|
152 "boilerplate". ``a`` will be an instance of ``A``, which is a subtype |
|
153 of :class:`Complex` (``a : A <: Complex``), and ``b : B <: |
|
154 Complex``. 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 |
|
174 If ``A<:Complex`` and ``B<:Real`` without sharing any other knowledge, |
|
175 then the appropriate shared operation is the one involving the built |
|
176 in :class:`complex`, and both :meth:`__radd__` s land there, so ``a+b |
|
177 == b+a``. |
|
178 |
|
179 Because most of the operations on any given type will be very similar, |
|
180 it can be useful to define a helper function which generates the |
|
181 forward and reverse instances of any given operator. For example, |
|
182 :class:`fractions.Fraction` uses:: |
|
183 |
|
184 def _operator_fallbacks(monomorphic_operator, fallback_operator): |
|
185 def forward(a, b): |
|
186 if isinstance(b, (int, long, Fraction)): |
|
187 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): |
|
198 if isinstance(a, Rational): |
|
199 # 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""" |
|
214 return Fraction(a.numerator * b.denominator + |
|
215 b.numerator * a.denominator, |
|
216 a.denominator * b.denominator) |
|
217 |
|
218 __add__, __radd__ = _operator_fallbacks(_add, operator.add) |
|
219 |
|
220 # ... |