其他分享
首页 > 其他分享> > 我如何重载运算符,以使左侧/右侧的类型无关紧要?

我如何重载运算符,以使左侧/右侧的类型无关紧要?

作者:互联网

一个简单的例子-我想要一个点类,它在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