我如何重载运算符,以使左侧/右侧的类型无关紧要?
作者:互联网
一个简单的例子-我想要一个点类,它在2维中描述一个点.而且我希望能够将两个点相加…以及将两个点相乘(不要问我为什么),或者将一个点乘以标量.现在,我仅将其实现为标量是整数,但分数或浮点数也很简单.
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __str__(self):
return "({0},{1})".format(self.x, self.y)
def __add__(self, other):
x = self.x + other.x
y = self.y + other.y
return Point(x, y)
def __mul__(self, other):
if isinstance(other, Point):
x = self.x * other.x
y = self.y * other.y
return Point(x, y)
elif isinstance(other, int):
x = self.x * other
y = self.y * other
return Point(x, y)
因此,这在我执行以下操作时有效:
>>> p1 = Point(2, 3)
>>> p2 = Point(-1, 2)
>>> print(p1*p2)
(-2,6)
>>>print(p1*4)
(8,12)
但是当我反转标量和Point对象的顺序时,它不起作用:
>>>print(4*p1)
Traceback (most recent call last):
File "<input>", line 1, in <module> TypeError: unsupported operand type(s) for *:
'int' and 'Point'
如果我写’4 * p1’或’p1 * 4’仍将执行相同的代码并返回相同的答案,那么该如何写无关紧要的代码?我是通过将mul运算符重载为int对象还是通过另一种方式来实现此目的?
注意:我的简短示例代码是从https://www.programiz.com/python-programming/operator-overloading借来的
解决方法:
(当我要提交问题时,我正在标记并找到了答案.我认为值得在此处进行记录,以便其他人可以轻松地找到它.)
定义__rmul __(自己,其他).这代表右乘.当左边的对象不能相乘时(在上面的示例中,整数不知道如何相乘右边的Point类),Python将查看右边的对象,以查看__rmul __(self,other)是否特殊方法已定义,并且有效吗?如果是这样,它将改用此实现.
对于可交换的类(即,您可以将AB或BA相乘并获得相同的结果),可以将其定义为:
def __mul__(self, other):
if isinstance(other, Point):
x = self.x * other.x
y = self.y * other.y
return Point(x, y)
elif isinstance(other, int):
x = self.x * other
y = self.y * other
return Point(x, y)
def __rmul__(self, other):
return self.__mul__(other)
标签:operator-overloading,python 来源: https://codeday.me/bug/20191110/2013705.html