2011-04-09 25 views
6

Esencialmente Quiero ser capaz de hacer algo como:Creando mi propio objeto "entero" en Python

a = Integer(1) 
a += 1 
print a 

Y, por supuesto, imprimir el número dos como consecuencia de ello. ¿Qué métodos necesito crear para obtener este comportamiento en mi clase Integer?

Descargo de responsabilidad: No estoy planeando usar esto para "real", solo curiosidad.

+2

Consulte también http://stackoverflow.com/questions/1638229. – FMc

+2

Lea esto: http://docs.python.org/library/numbers.html#module-numbers. Después de leer eso, ** actualice ** su pregunta para ser más específico. –

+0

@FM gracias, eso estuvo bien! –

Respuesta

8

Este es un ejemplo simple e incompleto. Mire los métodos __sub__, __div__ y así sucesivamente.

class Integer(object) : 
    def __init__(self, val=0) : 
     self._val = int(val) 
    def __add__(self, val) : 
     if type(val) == Integer : 
      return Integer(self._val + val._val) 
     return self._val + val 
    def __iadd__(self, val) : 
     self._val += val 
     return self 
    def __str__(self) : 
     return str(self._val) 
    def __repr__(self) : 
     return 'Integer(%s)' %self._val 

Entonces

n = Integer() 
print n 
m = Integer(7) 
m+=5 
print m 

EDITAR fijo __repr__ y añadido __iadd__. Gracias a @Keith por señalar problemas. EDIT Se corrigió __add__ para permitir la adición entre enteros.

+0

Este ejemplo mal utiliza '__repr__'. Eso tiene la intención de devolver el inverso de 'eval()' y debería devolver 'Integer (val)' en este caso.También no mantiene el tipo: 'python2> m = entero (7) python2> tipo (m) python2> m + = 5 python2> tipo (m) ' – Keith

+0

@Keith bien visto, gracias. – juanchopanza

+0

Debería ser '__str__'. – TryPyPy

3

Puede utilizar operator overloading:

class Integer: 

    def __init__(self, value): 
    self.value = value 

    def __repr__(self): 
    return str(self.value) 

    def __add__(self, value): 
    self.value += value 
    return self 

a = Integer(2) 
print a 

a = a+3 
print a 

a += 4 
print a 
3

Asumo que quiere que su clase de entero a ser mutable. Para obtener su ejemplo, esto va a funcionar:

class Integer(object): 
    def __init__(self, num): 
     self._val = num 

    def __iadd__(self, other): 
     self._val += int(other) 

    def __str__(self): 
     return str(self._val) 
6

En primer lugar, echar un vistazo rápido a la documentación en el manual de referencia sobre emulating numeric types.

(No demasiado pegado en que - es sólo para darle una cierta familiaridad con los métodos de operaciones aritméticas subyacentes en Python)

A continuación, se refieren a la documentación de la numbers module, que incluye todas las clases base abstractas que son más relevantes para emular diferentes tipos de números (por ejemplo, numbers.Integral para enteros personalizados).

3

Si desea sobrecargar los operadores del método de fundición a cadena predeterminada, la frase que estás buscando es "métodos mágicos". Estos son los métodos denominados como "__<name>__" y Python los utiliza en casos distintos a las llamadas a métodos directos. Debería definir los métodos __add__ y __str__ para su clase para que las líneas 2 y 3, respectivamente, funcionen.

Vale la pena mencionar que se llamará al método __add__ si su nuevo tipo es el operando izquierdo, y cualquier tipo puede pasar como su argumento. Para los casos en que el suyo es el operando correcto, también debe definir el método __radd__. Esto aplica a todos los operadores binarios.

Para una lista más completa de los métodos mágicos para un tipo numérico, ver Emulating Numeric Types.

1
class Integer(object): 

    def __init__(self, value=0): 
     self._value = int(value) 

    def __add__(self, other): 
     if isinstance(other, Integer): 
      return Integer(self._value + other._value) 
     return Integer(self._value + other) 

    def __iadd__(self, other): 
     if isinstance(other, Integer): 
      self._value += other._value 
     else: 
      self._value += other 
     return self 

    def __sub__(self, other): 
     if isinstance(other, Integer): 
      return Integer(self._value - other._value) 
     return Integer(self._value - other) 

    def __isub__(self, other): 
     if isinstance(other, Integer): 
      self._value -= other._value 
     else: 
      self._value -= other 
     return self 

    def __mul__(self, other): 
     if isinstance(other, Integer): 
      return Integer(self._value * other._value) 
     return Integer(self._value * other) 

    def __div__(self, other): 
     if isinstance(other, Integer): 
      return Integer(self._value/other._value) 
     return Integer(self._value/other) 

    def __str__(self): 
     return str(self._value) 

    def __int__(self): 
     return self._value 

    def __float__(self): 
     return float(self._value) 

    def __repr__(self): 
     return 'Integer(%s)' % self._value 
Cuestiones relacionadas