numbers — Clase base abstracta numérica¶
Código fuente: Lib/numbers.py
El módulo numbers (PEP 3141) define una jerarquía de abstract base classes numérico que define progresivamente más operaciones. Ninguno de los tipos definidos en este módulo está destinado a ser instanciado.
- 
class 
numbers.Number¶ La raíz de la jerarquía numérica. Si desea validar si un argumento x es un número, sin importar su tipo, use
isinstance(x, Number).
La torre numérica¶
- 
class 
numbers.Complex¶ Las subclases de este tipo describen números complejos e incluyen las operaciones que funcionan en el tipo
complexintegrado. Estos son: conversiones acomplexybool,real,imag,+,-,*,/,**,abs(),conjugate(),==y!=. Todos excepto-y!=son abstractos.- 
real¶ Abstracto. Recupera el componente real de este número.
- 
imag¶ Abstracto. Recupera el componente imaginario de este número.
- 
abstractmethod 
conjugate()¶ Abstracto. Retorna el complejo conjugado. Por ejemplo,
(1+3j).conjugate() == (1-3j).
- 
 
- 
class 
numbers.Real¶ Para
Complex,Realagrega las operaciones que trabajan con números reales.En resumen, estos son: conversiones a
float,math.trunc(),round(),math.floor(),math.ceil(),divmod(),//,%,<,<=,>, y>=.Real también proporciona valores predeterminados para
complex(),real,imag, yconjugate().
- 
class 
numbers.Rational¶ Subtypes
Realand addsnumeratoranddenominatorproperties. It also provides a default forfloat().The
numeratoranddenominatorvalues should be instances ofIntegraland should be in lowest terms withdenominatorpositive.- 
numerator¶ Abstracto.
- 
denominator¶ Abstracto.
- 
 
Notas para implementadores de tipos¶
Los implementadores deben tener cuidado de igualar números iguales y aplicar un hash a los mismos valores. Esto puede ser sutil si hay dos extensiones diferentes de los números reales. Por ejemplo, fractions.Fraction implementa hash() de la siguiente manera:
def __hash__(self):
    if self.denominator == 1:
        # Get integers right.
        return hash(self.numerator)
    # Expensive check, but definitely correct.
    if self == float(self):
        return hash(float(self))
    else:
        # Use tuple's hash to avoid a high collision rate on
        # simple fractions.
        return hash((self.numerator, self.denominator))
Agregar más ABCs numéricos¶
Por supuesto, hay más ABCs posibles para los números, y esto sería una jerarquía deficiente si se excluye la posibilidad de añadirlos. Puede usar MyFoo entre Complex y Real así:
class MyFoo(Complex): ...
MyFoo.register(Real)
Implementar operaciones aritméticas¶
Queremos implementar las operaciones aritméticas tal que las operaciones de modo mixto llamen a una implementación cuyo autor conocía los tipos de ambos argumentos, o convertir ambos argumentos al tipo incorporado más cercano antes de hacer la operación. Para subtipos de Integral, esto significa que __add__() y __radd__() tienen que ser definidos como:
class MyIntegral(Integral):
    def __add__(self, other):
        if isinstance(other, MyIntegral):
            return do_my_adding_stuff(self, other)
        elif isinstance(other, OtherTypeIKnowAbout):
            return do_my_other_adding_stuff(self, other)
        else:
            return NotImplemented
    def __radd__(self, other):
        if isinstance(other, MyIntegral):
            return do_my_adding_stuff(other, self)
        elif isinstance(other, OtherTypeIKnowAbout):
            return do_my_other_adding_stuff(other, self)
        elif isinstance(other, Integral):
            return int(other) + int(self)
        elif isinstance(other, Real):
            return float(other) + float(self)
        elif isinstance(other, Complex):
            return complex(other) + complex(self)
        else:
            return NotImplemented
Hay 5 casos diferentes para una operación de tipo mixto en subclases de Complex. Se explicará  todo el código anterior que no se refiere a MyIntegral y OtherTypeIKnowAbout` como "repetitivo". ``a será una instancia de A, que es un subtipo de Complex (a: A <: Complex`), y ``b : B <: Complex. Consideraré a + b:
Si
Adefine un__add__()que aceptab, todo está bien.Si
Arecurre al código repetitivo y retorna un valor de__add__(), perderíamos la posibilidad de que B defina un__radd __()más inteligente, por lo que el código repetitivo debería retornarNotImplementedde__add__(). (OAno puede implementar__add__()en absoluto.)Entonces
B’s__radd__()tiene una oportunidad. Si aceptaa, todo esta bien.Si se vuelve a caer en el código repetitivo, no hay más posibles métodos para probar, por lo que acá debería vivir la implementación predeterminada.
Si
B <: A, Python probaraB.__radd__antes queA.__add__. Esto está bien, porque se implementó con conocimiento deA, por lo que puede manejar instancias antes de delegar unComplex.
Si A <: Complex y B <: Real sin compartir ningún otro conocimiento,la operación compartida apropiada es la que involucra la clase complex incorporada, y ambos __radd__() desencadenan allí, entonces a+b == b+a.
Dado que la mayoría de las operaciones en un tipo determinado serán muy similares, puede ser útil definir una función auxiliar que genere las instancias forward y reverse de cualquier operador dado. Por ejemplo, fractions.Fraction así:
def _operator_fallbacks(monomorphic_operator, fallback_operator):
    def forward(a, b):
        if isinstance(b, (int, Fraction)):
            return monomorphic_operator(a, b)
        elif isinstance(b, float):
            return fallback_operator(float(a), b)
        elif isinstance(b, complex):
            return fallback_operator(complex(a), b)
        else:
            return NotImplemented
    forward.__name__ = '__' + fallback_operator.__name__ + '__'
    forward.__doc__ = monomorphic_operator.__doc__
    def reverse(b, a):
        if isinstance(a, Rational):
            # Includes ints.
            return monomorphic_operator(a, b)
        elif isinstance(a, numbers.Real):
            return fallback_operator(float(a), float(b))
        elif isinstance(a, numbers.Complex):
            return fallback_operator(complex(a), complex(b))
        else:
            return NotImplemented
    reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
    reverse.__doc__ = monomorphic_operator.__doc__
    return forward, reverse
def _add(a, b):
    """a + b"""
    return Fraction(a.numerator * b.denominator +
                    b.numerator * a.denominator,
                    a.denominator * b.denominator)
__add__, __radd__ = _operator_fallbacks(_add, operator.add)
# ...