17db96d56Sopenharmony_ci:mod:`numbers` --- Numeric abstract base classes 27db96d56Sopenharmony_ci================================================ 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci.. module:: numbers 57db96d56Sopenharmony_ci :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.). 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ci**Source code:** :source:`Lib/numbers.py` 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci-------------- 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ciThe :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric 127db96d56Sopenharmony_ci:term:`abstract base classes <abstract base class>` which progressively define 137db96d56Sopenharmony_cimore operations. None of the types defined in this module are intended to be instantiated. 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci 167db96d56Sopenharmony_ci.. class:: Number 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ci The root of the numeric hierarchy. If you just want to check if an argument 197db96d56Sopenharmony_ci *x* is a number, without caring what kind, use ``isinstance(x, Number)``. 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_ciThe numeric tower 237db96d56Sopenharmony_ci----------------- 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci.. class:: Complex 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci Subclasses of this type describe complex numbers and include the operations 287db96d56Sopenharmony_ci that work on the built-in :class:`complex` type. These are: conversions to 297db96d56Sopenharmony_ci :class:`complex` and :class:`bool`, :attr:`.real`, :attr:`.imag`, ``+``, 307db96d56Sopenharmony_ci ``-``, ``*``, ``/``, ``**``, :func:`abs`, :meth:`conjugate`, ``==``, and 317db96d56Sopenharmony_ci ``!=``. All except ``-`` and ``!=`` are abstract. 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci .. attribute:: real 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_ci Abstract. Retrieves the real component of this number. 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci .. attribute:: imag 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci Abstract. Retrieves the imaginary component of this number. 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci .. abstractmethod:: conjugate() 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_ci Abstract. Returns the complex conjugate. For example, ``(1+3j).conjugate() 447db96d56Sopenharmony_ci == (1-3j)``. 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci.. class:: Real 477db96d56Sopenharmony_ci 487db96d56Sopenharmony_ci To :class:`Complex`, :class:`Real` adds the operations that work on real 497db96d56Sopenharmony_ci numbers. 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_ci In short, those are: a conversion to :class:`float`, :func:`math.trunc`, 527db96d56Sopenharmony_ci :func:`round`, :func:`math.floor`, :func:`math.ceil`, :func:`divmod`, ``//``, 537db96d56Sopenharmony_ci ``%``, ``<``, ``<=``, ``>``, and ``>=``. 547db96d56Sopenharmony_ci 557db96d56Sopenharmony_ci Real also provides defaults for :func:`complex`, :attr:`~Complex.real`, 567db96d56Sopenharmony_ci :attr:`~Complex.imag`, and :meth:`~Complex.conjugate`. 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci.. class:: Rational 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci Subtypes :class:`Real` and adds :attr:`~Rational.numerator` and 627db96d56Sopenharmony_ci :attr:`~Rational.denominator` properties. It also provides a default for 637db96d56Sopenharmony_ci :func:`float`. 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci The :attr:`~Rational.numerator` and :attr:`~Rational.denominator` values 667db96d56Sopenharmony_ci should be instances of :class:`Integral` and should be in lowest terms with 677db96d56Sopenharmony_ci :attr:`~Rational.denominator` positive. 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci .. attribute:: numerator 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci Abstract. 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci .. attribute:: denominator 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci Abstract. 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ci.. class:: Integral 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_ci Subtypes :class:`Rational` and adds a conversion to :class:`int`. Provides 817db96d56Sopenharmony_ci defaults for :func:`float`, :attr:`~Rational.numerator`, and 827db96d56Sopenharmony_ci :attr:`~Rational.denominator`. Adds abstract methods for :func:`pow` with 837db96d56Sopenharmony_ci modulus and bit-string operations: ``<<``, ``>>``, ``&``, ``^``, ``|``, 847db96d56Sopenharmony_ci ``~``. 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ciNotes for type implementors 887db96d56Sopenharmony_ci--------------------------- 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ciImplementors should be careful to make equal numbers equal and hash 917db96d56Sopenharmony_cithem to the same values. This may be subtle if there are two different 927db96d56Sopenharmony_ciextensions of the real numbers. For example, :class:`fractions.Fraction` 937db96d56Sopenharmony_ciimplements :func:`hash` as follows:: 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci def __hash__(self): 967db96d56Sopenharmony_ci if self.denominator == 1: 977db96d56Sopenharmony_ci # Get integers right. 987db96d56Sopenharmony_ci return hash(self.numerator) 997db96d56Sopenharmony_ci # Expensive check, but definitely correct. 1007db96d56Sopenharmony_ci if self == float(self): 1017db96d56Sopenharmony_ci return hash(float(self)) 1027db96d56Sopenharmony_ci else: 1037db96d56Sopenharmony_ci # Use tuple's hash to avoid a high collision rate on 1047db96d56Sopenharmony_ci # simple fractions. 1057db96d56Sopenharmony_ci return hash((self.numerator, self.denominator)) 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_ciAdding More Numeric ABCs 1097db96d56Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~ 1107db96d56Sopenharmony_ci 1117db96d56Sopenharmony_ciThere are, of course, more possible ABCs for numbers, and this would 1127db96d56Sopenharmony_cibe a poor hierarchy if it precluded the possibility of adding 1137db96d56Sopenharmony_cithose. You can add ``MyFoo`` between :class:`Complex` and 1147db96d56Sopenharmony_ci:class:`Real` with:: 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_ci class MyFoo(Complex): ... 1177db96d56Sopenharmony_ci MyFoo.register(Real) 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ci.. _implementing-the-arithmetic-operations: 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_ciImplementing the arithmetic operations 1237db96d56Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ciWe want to implement the arithmetic operations so that mixed-mode 1267db96d56Sopenharmony_cioperations either call an implementation whose author knew about the 1277db96d56Sopenharmony_citypes of both arguments, or convert both to the nearest built in type 1287db96d56Sopenharmony_ciand do the operation there. For subtypes of :class:`Integral`, this 1297db96d56Sopenharmony_cimeans that :meth:`__add__` and :meth:`__radd__` should be defined as:: 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_ci class MyIntegral(Integral): 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci def __add__(self, other): 1347db96d56Sopenharmony_ci if isinstance(other, MyIntegral): 1357db96d56Sopenharmony_ci return do_my_adding_stuff(self, other) 1367db96d56Sopenharmony_ci elif isinstance(other, OtherTypeIKnowAbout): 1377db96d56Sopenharmony_ci return do_my_other_adding_stuff(self, other) 1387db96d56Sopenharmony_ci else: 1397db96d56Sopenharmony_ci return NotImplemented 1407db96d56Sopenharmony_ci 1417db96d56Sopenharmony_ci def __radd__(self, other): 1427db96d56Sopenharmony_ci if isinstance(other, MyIntegral): 1437db96d56Sopenharmony_ci return do_my_adding_stuff(other, self) 1447db96d56Sopenharmony_ci elif isinstance(other, OtherTypeIKnowAbout): 1457db96d56Sopenharmony_ci return do_my_other_adding_stuff(other, self) 1467db96d56Sopenharmony_ci elif isinstance(other, Integral): 1477db96d56Sopenharmony_ci return int(other) + int(self) 1487db96d56Sopenharmony_ci elif isinstance(other, Real): 1497db96d56Sopenharmony_ci return float(other) + float(self) 1507db96d56Sopenharmony_ci elif isinstance(other, Complex): 1517db96d56Sopenharmony_ci return complex(other) + complex(self) 1527db96d56Sopenharmony_ci else: 1537db96d56Sopenharmony_ci return NotImplemented 1547db96d56Sopenharmony_ci 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ciThere are 5 different cases for a mixed-type operation on subclasses 1577db96d56Sopenharmony_ciof :class:`Complex`. I'll refer to all of the above code that doesn't 1587db96d56Sopenharmony_cirefer to ``MyIntegral`` and ``OtherTypeIKnowAbout`` as 1597db96d56Sopenharmony_ci"boilerplate". ``a`` will be an instance of ``A``, which is a subtype 1607db96d56Sopenharmony_ciof :class:`Complex` (``a : A <: Complex``), and ``b : B <: 1617db96d56Sopenharmony_ciComplex``. I'll consider ``a + b``: 1627db96d56Sopenharmony_ci 1637db96d56Sopenharmony_ci 1. If ``A`` defines an :meth:`__add__` which accepts ``b``, all is 1647db96d56Sopenharmony_ci well. 1657db96d56Sopenharmony_ci 2. If ``A`` falls back to the boilerplate code, and it were to 1667db96d56Sopenharmony_ci return a value from :meth:`__add__`, we'd miss the possibility 1677db96d56Sopenharmony_ci that ``B`` defines a more intelligent :meth:`__radd__`, so the 1687db96d56Sopenharmony_ci boilerplate should return :const:`NotImplemented` from 1697db96d56Sopenharmony_ci :meth:`__add__`. (Or ``A`` may not implement :meth:`__add__` at 1707db96d56Sopenharmony_ci all.) 1717db96d56Sopenharmony_ci 3. Then ``B``'s :meth:`__radd__` gets a chance. If it accepts 1727db96d56Sopenharmony_ci ``a``, all is well. 1737db96d56Sopenharmony_ci 4. If it falls back to the boilerplate, there are no more possible 1747db96d56Sopenharmony_ci methods to try, so this is where the default implementation 1757db96d56Sopenharmony_ci should live. 1767db96d56Sopenharmony_ci 5. If ``B <: A``, Python tries ``B.__radd__`` before 1777db96d56Sopenharmony_ci ``A.__add__``. This is ok, because it was implemented with 1787db96d56Sopenharmony_ci knowledge of ``A``, so it can handle those instances before 1797db96d56Sopenharmony_ci delegating to :class:`Complex`. 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ciIf ``A <: Complex`` and ``B <: Real`` without sharing any other knowledge, 1827db96d56Sopenharmony_cithen the appropriate shared operation is the one involving the built 1837db96d56Sopenharmony_ciin :class:`complex`, and both :meth:`__radd__` s land there, so ``a+b 1847db96d56Sopenharmony_ci== b+a``. 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ciBecause most of the operations on any given type will be very similar, 1877db96d56Sopenharmony_ciit can be useful to define a helper function which generates the 1887db96d56Sopenharmony_ciforward and reverse instances of any given operator. For example, 1897db96d56Sopenharmony_ci:class:`fractions.Fraction` uses:: 1907db96d56Sopenharmony_ci 1917db96d56Sopenharmony_ci def _operator_fallbacks(monomorphic_operator, fallback_operator): 1927db96d56Sopenharmony_ci def forward(a, b): 1937db96d56Sopenharmony_ci if isinstance(b, (int, Fraction)): 1947db96d56Sopenharmony_ci return monomorphic_operator(a, b) 1957db96d56Sopenharmony_ci elif isinstance(b, float): 1967db96d56Sopenharmony_ci return fallback_operator(float(a), b) 1977db96d56Sopenharmony_ci elif isinstance(b, complex): 1987db96d56Sopenharmony_ci return fallback_operator(complex(a), b) 1997db96d56Sopenharmony_ci else: 2007db96d56Sopenharmony_ci return NotImplemented 2017db96d56Sopenharmony_ci forward.__name__ = '__' + fallback_operator.__name__ + '__' 2027db96d56Sopenharmony_ci forward.__doc__ = monomorphic_operator.__doc__ 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_ci def reverse(b, a): 2057db96d56Sopenharmony_ci if isinstance(a, Rational): 2067db96d56Sopenharmony_ci # Includes ints. 2077db96d56Sopenharmony_ci return monomorphic_operator(a, b) 2087db96d56Sopenharmony_ci elif isinstance(a, Real): 2097db96d56Sopenharmony_ci return fallback_operator(float(a), float(b)) 2107db96d56Sopenharmony_ci elif isinstance(a, Complex): 2117db96d56Sopenharmony_ci return fallback_operator(complex(a), complex(b)) 2127db96d56Sopenharmony_ci else: 2137db96d56Sopenharmony_ci return NotImplemented 2147db96d56Sopenharmony_ci reverse.__name__ = '__r' + fallback_operator.__name__ + '__' 2157db96d56Sopenharmony_ci reverse.__doc__ = monomorphic_operator.__doc__ 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci return forward, reverse 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_ci def _add(a, b): 2207db96d56Sopenharmony_ci """a + b""" 2217db96d56Sopenharmony_ci return Fraction(a.numerator * b.denominator + 2227db96d56Sopenharmony_ci b.numerator * a.denominator, 2237db96d56Sopenharmony_ci a.denominator * b.denominator) 2247db96d56Sopenharmony_ci 2257db96d56Sopenharmony_ci __add__, __radd__ = _operator_fallbacks(_add, operator.add) 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ci # ... 228