2009-07-12 13 views
7

No lo creo, pero pensé que podría preguntar por las dudas. Por ejemplo, para su uso en una clase que encapsula un int:¿python tiene operadores de conversión?

i = IntContainer(3) 
i + 5 

Y no soy sólo interesado en este ejemplo int, que estaba buscando algo limpio y en general, no anulando todos los int y método de cadena.

Gracias, sunqiang. Eso es justo lo que quería. No me di cuenta de que podías subclasificar estos tipos inmutables (procedentes de C++).

class IntContainer(int): 
    def __init__(self,i): 
     #do stuff here 
     self.f = 4 

    def MultiplyBy4(self): 
     #some member function 
     self *= self.f 
     return self 

print 3+IntContainer(3).MultiplyBy4() 

Respuesta

3

a veces tal vez solo la subclase de int directamente es suficiente. entonces __add__ y __radd__ no necesitan vestirse.

class IntContainer(int): 
    pass 
i = IntContainer(3) 
print i + 5 # 8 
print 4 + i # 7 

class StrContainer(str): 
    pass 
s = StrContainer(3) 
print s + '5' # 35 
print '4' + s # 43 
3

¿Es esto lo que necesita?

In [1]: class IntContainer(object): 
    ...:  def __init__(self, val): 
    ...:   self.val = val 
    ...:  def __add__(self, val): 
    ...:   return self.val + val 
    ...:  def __radd__(self, val): 
    ...:   return self.val + val 
    ...: 
    ...: 

In [2]: i = IntContainer(3) 

In [3]: i + 5 
Out[3]: 8 

In [4]: 
+1

No realmente. Estaba buscando algo así como el operador de conversión C++, que inteligentemente reemplaza el objeto contenedor con todo lo que contiene en expresiones. – Alex

+0

Esto no funcionará para "5 + i", creo. – ars

+0

ars, tienes razón, vi tu respuesta y me falta __radd__ ... creo que ahora está bien después de haber cambiado mi respuesta ... –

11

Esto debería hacer lo que tiene:

class IntContainer(object): 
    def __init__(self, x): 
     self.x = x 

    def __add__(self, other): 
     # do some type checking on other 
     return self.x + other 

    def __radd__(self, other): 
     # do some type checking on other 
     return self.x + other 

Salida:

In [6]: IntContainer(3) + 6 
Out[6]: 9 

In [7]: 6 + IntContainer(3) 
Out[7]: 9 

Para obtener más información de búsqueda para "radd" en los siguientes documentos:

Encontrará otros métodos para "Además derecha", "resta derecha", etc.

Aquí hay otro enlace que cubre los mismos operadores:

Por cierto, Python tiene operadores de casting:

embargo, no van a lograr lo que necesita en su ejemplo (básicamente porque los métodos no tienen ninguna anotación de tipo de parámetros, así que no hay buena manera de echar implícitamente). Así que usted puede hacer esto:

class IntContainer2(object): 
    def __init__(self, x): 
     self.x = x 

    def __int__(self): 
     return self.x 


ic = IntContainer2(3) 
print int(ic) + 6 
print 6 + int(ic) 

Pero esto va a fracasar:

print ic + 6 # error: no implicit coercion 
3

Usted no recibirá operadores de conversión como en C++ Python porque no tiene este tipo de sistema fuerte de tipo estático. Los únicos operadores de conversión automática son aquellos que manejan valores numéricos predeterminados (int/float); están predefinidos en el idioma y no se pueden cambiar.

El tipo "conversión" generalmente es realizado por constructores/fábricas. A continuación, puede sobrecargar métodos estándar como __add__ para que funcione más como otras clases.

0

Lo sentimos por venir a la fiesta 8,5 años tarde. Puede derivar de un inmutable (es decir, int). No puede definir __init__ porque el inmutable ya está creado y no se puede modificar (por definición). Aquí es donde __new__ es útil.

class IntContainer(int): 
    def __new__ (cls, val): 
     ival = int.__new__(cls, val) 
     ival._rval = 'IntContainer(%d)' % ival 
     return ival 
    def __repr__ (self): 
     return self._rval 

In [1]: i = IntContainer(3) 

In [2]: i 
Out[2]: IntContainer(3) 

In [3]: repr(i) 
Out[3]: 'IntContainer(3)' 

In [4]: str(i) 
Out[4]: '3' 

In [5]: i + 5 
Out[5]: 8 

In [6]: 4 + i 
Out[6]: 7 

In [7]: int(i) 
Out[7]: 3 

In [8]: float(i) 
Out[8]: 3.0 

Ahora, para responder a su pregunta sobre los operadores de conversión. También puede definir __int__, __long__, __float__, y obviamente, __str__. Para convertir o convertir a un objeto arbitrario, lo más probable es que necesite modificar el otro objeto para obtener lo que desea. Puede usar el método __new__ de ese otro objeto. O si el otro objeto ya está creado, intente usar __call__.

Cuestiones relacionadas