2010-07-06 17 views
5

Me gustaría que el operador de mi clase pueda interactuar con los tipos normales de la forma que defino. Digamos, por ejemplo, que tengo:Python: Operador Sobrecarga de un tipo específico

class Mynum(object): 
    def __init__(self, x): 
    self.x = x 
    def __add__(self, other): 
    return self.x + other.x 

a = Mynum(1) 
b = Mynum(2) 

print a+b 

Esto funciona bien, pero ahora si trato de hacer:

print a+2 

me sale un error, ya que un int no tenga un miembro nombrado x . ¿Cómo se define Mynum + int en la clase? Esto suena como un trabajo para decoradores o metaclases, pero estoy terriblemente familiarizado con su uso. This question parece similar, pero no del todo idéntico.

+0

verifique el tipo o 'otro' o la presencia del atributo 'x'. – SilentGhost

+0

no se olvide de hacer: '' __radd__' = __add__' también (a pesar de que no resolviera el problema) – jcao219

Respuesta

11
def __add__(self, other): 
    if isinstance(other, self.__class__): 
     return self.x + other.x 
    elif isinstance(other, int): 
     return self.x + other 
    else: 
     raise TypeError("unsupported operand type(s) for +: '{}' and '{}'").format(self.__class__, type(other)) 
+0

Gracias, nunca he visto 'isinstance' antes. ¿Se considera que esta es la forma correcta de hacerlo, o debería usar el bloque try/except propuesto por unutbu? – Hooked

+0

La cláusula 'try ... except' es rápida cuando no se produce ninguna excepción, y lenta de lo contrario. Por lo tanto, puede usarlo si agregar dos instancias de su clase es el uso más común de la adición sobrecargada. De lo contrario, el enfoque 'insinstance' es bueno. – EOL

+0

¿No debería devolver 'NotImplemented' en lugar de subir y hacer una excepción usted mismo? – jpcgt

4
class Mynum(object): 
    def __init__(self, x): 
     self.x = x 
    def __add__(self, other): 
     try: 
      return self.x + other.x 
     except AttributeError: 
      return self.x + other 
    __radd__=__add__ 

a = Mynum(1) 
b = Mynum(2) 

print(a+b) 
# 3 
print(a+2) 
# 3 
print(2+a) 
# 3 
2

¿Por qué utilizar la conmutación adicional y/o manejo de excepciones? El uso de lo siguiente sería un enfoque más simple:

class MyNum(object): 
    def __init__(self, x): 
     self.x = x 
    def __add__(self, other): 
     return other + self.x 
    __radd__ = __add__ 
x = MyNum(5) 
y = MyNum(6) 
print x + 2 
7 
print 2 + x 
7 
print x + y 
11 
print y + x 
11