Para cada signo de operador, hay un mecanismo subyacente. Este mecanismo subyacente es un método especial que se llamará durante la acción del operador. Este método especial se llama método mágico . Para cada cálculo aritmético como +, -, *, /, necesitamos 2 operandos para llevar a cabo la funcionalidad del operador.
Ejemplos:
‘+’ ? ‘__add__’ method ‘_’ ? ‘__sub__’ method ‘*’ ? ‘__mul__’ method
Como el artículo se limita a la funcionalidad de multiplicación, veremos aquí el procedimiento de multiplicación. Para realizar la función de multiplicación, tenemos que vincular el signo del operador a cualquiera de los operandos izquierdo/derecho. Antes de ir al __rmul__
método, veremos sobre __mul__
el método, que nos ayuda a comprender vívidamente la funcionalidad de la multiplicación.
__mul__()
Tomemos una expresión x*y
donde x es una instancia de una clase A. Para realizar el __mul__
método, el operador busca en la clase del operando izquierdo (x) el presente de __mul__, es decir, el operador (*) verificará la presencia de la clase A de ‘ __mul__
‘ método en él. Si tiene un __mul__
método, llama a x.__mul__(y)
. De lo contrario, arroja el mensaje de error ‘ TypeError: operandos no admitidos ‘.
Ejemplo 1:
class Foo(object): def __init__(self, val): self.val = val def __str__(self): return "Foo [% s]" % self.val class Bar(object): def __init__(self, val): self.val = val def __str__(self): return "Bar [% s]" % self.val # Driver Code f = Foo(5) b = Bar(6) print(f * b)
Producción:
TypeError, unsupported operand type(s) for *: 'Foo' and 'Bar'
En el ejemplo anterior, el primer operando es f y su clase Foo(). Como Foo() no tiene __mul__
método, no entiende cómo multiplicar. Entonces, aparecerá el mensaje TypeError. Si comprobamos la otra clase Bar(), ni siquiera tiene __mul__
método. Entonces, incluso si invertimos la multiplicación a (b*f), arrojará el mismo error
Ejemplo 2: Agreguemos el método __mul__ en la clase Foo.
class Foo(object): def __init__(self, val): self.val = val def __mul__(self, other): return Foo(self.val * other.val) def __str__(self): return "Foo [% s]" % self.val class Bar(object): def __init__(self, val): self.val = val def __str__(self): return "Bar [% s]" % self.val # Driver Code f = Foo(5) b = Bar(6) print(f * b)
Producción:
Foo 30
Como ya se mencionó, el operador por defecto busca en la clase del operando izquierdo, y aquí encuentra el método __mul__. Ahora sabe qué hacer y resultó 30 f.__mul__(b) = 5.__mul__(6)
. Si invertimos la multiplicación a (b*f), vuelve a surgir el problema, ya que busca en la clase del operando izquierdo (Bar()) que no tiene ningún __mul__
método. b.__mul__(f)
arrojará el problema ya que la clase Bar() de b no tiene __mul__
método.
__rmul__
Una ligera diferencia entre __mul__
y __rmul__
es que el Operador busca __mul__
en el operando izquierdo y busca __rmul__
en el operando derecho. Por ejemplo, x*y. El operador busca el __rmul__
método en la definición de clase de y. Si encuentra el __rmul__
método, aparecerá con el resultado; de lo contrario, arroja el mensaje de error TypeError
Ejemplo 1: Tomemos el ejemplo anterior con una pequeña modificación.
class Foo(object): def __init__(self, val): self.val = val def __str__(self): return "Foo [% s]" % self.val class Bar(object): def __init__(self, val): self.val = val def __rmul__(self, other): return Bar(self.val * other.val) def __str__(self): return "Bar [% s]" % self.val # Driver code f = Foo(5) b = Bar(6) print(f * b)
Producción:
Bar 30
En el ejemplo anterior, se supone que f*b ya b.__rmul__(f)
que el __rmul__
método está presente en la clase Bar() de la instancia b. Si invertimos la multiplicación a (b*f). La notación será f.__rmul__(b)
. Si no tiene un __rmul__
método, no puede entender qué anotar y arroja un mensaje TypeError.’
Este tipo de operadores, que requieren 2 operandos, llevarán por defecto ambos __mul__
y el __rmul__
método. Para realizar la multiplicación tanto con la multiplicación normal como con la inversa, consulte el siguiente ejemplo.
Ejemplo 2:
class Foo(object): def __init__(self, val): self.val = val def __str__(self): return "Foo [% s]" % self.val class Bar(object): def __init__(self, val): self.val = val def __rmul__(self, other): return Bar(self.val * other.val) def __mul__(self, other): return self.__rmul__(other) def __str__(self): return "Bar [% s]" % self.val # Driver Code f = Foo(5) b = Bar(6) print(b * f) print(f * b)
Producción:
Bar [30] Bar [30]
Publicación traducida automáticamente
Artículo escrito por krishna krish y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA