[英]How to implement multiplication between class instances and float and class instance in Python
I am trying to write a class that simulates a complex number in Python.我正在尝试编写一个在 Python 中模拟复数的类。 Yes, I know there already exists a built-in function called complex()
which can be used to construct a complex number, and we can also use j
to create them.是的,我知道已经有一个叫做complex()
的内置函数可以用来构造一个复数,我们也可以使用j
来创建它们。 However I wanted to write my own just for fun.但是我想自己写一个只是为了好玩。 Here is a small version of it:这是它的一个小版本:
class Complex:
def __init__(self, real: float = 0, img: float = 0):
self.real = real
self.img = img
self.num = (self.real, self.img)
def __repr__(self) -> str:
string = "{real}".format(real=self.real) if self.real != 0 else ""
# Want to have "a + bi", "a", "bi"
# Want to avoid "+ bi" or "a + "
if self.real != 0 and self.img < 0:
string += " - " # img will already have -
elif self.real != 0 and self.img > 0:
string += " + "
string += "{img}i".format(img=abs(self.img)) if self.img != 0 else ""
return string
def __add__(self, other: 'Complex') -> 'Complex':
return Complex(self.real + other.real, self.img + other.img)
def __sub__(self, other: 'Complex') -> 'Complex':
return Complex(self.real - other.real, self.img - other.img)
def __matmul__(self, other: 'Complex') -> 'Complex':
# (ac - bd)
real = self.real * other.real - self.img * other.img
# (ad + bc)
img = self.real * other.img + self.img * other.real
return Complex(real, img)
def __mul__(self, other):
return Complex(self.real * other, self.img * other)
def __rmul__(self, other):
return self.__mul__(other)
The issue is that I cannot find a way of defining the following:问题是我找不到定义以下内容的方法:
This is because when I multiply two class instances, it still calls __mul__
while it does not call __matmul__
.这是因为当我将两个类实例相乘时,它仍然调用__mul__
而它不调用__matmul__
。 I think __matmul__
should only work with @
operator.我认为__matmul__
应该只与@
运算符一起使用。 How can I make all of this work without having to use another operator ( @
) ?如何在不使用其他运算符 ( @
) 的情况下完成所有这些工作? I would like to use the standard *
operator.我想使用标准的*
运算符。
In this case, you have to test for type and execute the proper arithmetic based on type.在这种情况下,您必须测试类型并根据类型执行适当的算法。
class Complex:
def __init__(self, real: float = 0, img: float = 0):
self.real = real
self.img = img
self.num = (self.real, self.img)
def __repr__(self) -> str:
string = "{real}".format(real=self.real) if self.real != 0 else ""
# Want to have "a + bi", "a", "bi"
# Want to avoid "+ bi" or "a + "
if self.real != 0 and self.img < 0:
string += " - " # img will already have -
elif self.real != 0 and self.img > 0:
string += " + "
string += "{img}i".format(img=abs(self.img)) if self.img != 0 else ""
return string
def __add__(self, other):
if isinstance(other, Complex):
return Complex(self.real + other.real, self.img + other.img)
elif isinstance(other, int) or isinstance(other, float):
return Complex(self.real + other, self.img)
def __radd__(self, other):
return self + other
def __sub__(self, other):
if isinstance(other, Complex):
return Complex(self.real - other.real, self.img - other.img)
elif isinstance(other, int) or isinstance(other, float):
return Complex(self.real - other, self.img)
def __rsub__(self, other):
return -self + other
def __neg__(self):
return Complex(-self.real, -self.img)
def __mul__(self, other):
if isinstance(other, Complex):
real = self.real * other.real - self.img * other.img # (ac - bd)
img = self.real * other.img + self.img * other.real # (ad + bc)
return Complex(real, img)
elif isinstance(other, int) or isinstance(other, float):
return Complex(self.real * other, self.img * other)
def __rmul__(self, other):
return self * other
and a few tests:和一些测试:
a, b = Complex(1, 2), Complex(2, 1)
a + 2, 2 + a, a - 2, 2 - a, 2 * a, a * 2, a + b, b + a, a - b, b - a, a * b, b * a
output:输出:
(3 + 2i,
3 + 2i,
-1 + 2i,
1 - 2i,
2 + 4i,
2 + 4i,
3 + 3i,
3 + 3i,
-1 + 1i,
1 - 1i,
5i,
5i)
In the same vein, you can implement __iadd__
( +=
), __isub__
( -=
), __imul__
(*=), paying attention to mutate the argument instead of returning a new object.同样,您可以实现__iadd__
( +=
)、 __isub__
( -=
)、 __imul__
(*=),注意改变参数而不是返回一个新对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.