在二维向量类中重写__mul__以保持交换律

6
我已经定义了以下类:

我有定义了以下类:

class Point(object):

    def __repr__(self):
        return "("+str(self.x)+","+str(self.y)+")"

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, point):
        return Point(self.x+point.x,self.y+point.y)

    def __sub__(self, point):
        return Point(self.x-point.x,self.y-point.y)

    def __mul__(self, num):
         return Point(num*self.x,num*self.y)

    def length(self):
        return (self.x**2 + self.y**2)**.5

以下代码是有效的:

x = Point(1,2)
y = Point(1,3)
print x+y
print (y+x)
print (x-y)
print (y-x)
print y*3

带有输出:

(2,5)
(2,5)
(0,-1)
(0,1)
(3,9)

但这个并不行:
print 3*y

它会产生以下错误:
----> 1 print 3*y
TypeError: unsupported operand type(s) for *: 'int' and 'Point'

这是因为Point类被输入到int mul函数中,我猜。我怎样才能保留Point类的定义并且使3*y的结果与y*3相同?

2个回答

7
3 * y 

我们在左侧有一个 `int` 实例,在右侧有一个 `Point` 实例。`Point` 不是 `int` 的子类。在这种情况下,`int.__mul__` 类会首先处理此操作,而 `Point.__mul__` 将无法发挥作用。
您需要在您的类上实现 `Point.__rmul__` 来处理这种情况。

3

根据Wim的回答,这里是经过测试和工作的实现:

class Point(object):
    def __repr__(self):
        return "(" + str(self.x) + "," + str(self.y) + ")"

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, point):
        return Point(self.x + point.x, self.y + point.y)

    def __sub__(self, point):
        return Point(self.x - point.x, self.y - point.y)

    def __mul__(self, num):
        return Point(num * self.x, num * self.y)

    def __rmul__(self, num):
        return self.__mul__(num)

    def length(self):
        return self.x ** 2 + self.y ** 2


x = Point(1, 2)
y = Point(1, 3)

print(x + y)
print(y + x)
print(x - y)
print(y - x)
print(y * 3)
print(3 * y)

输出

(2,5)
(2,5)
(0,-1)
(0,1)
(3,9)
(3,9)

最后两个输出结果相等,说明操作是可交换的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接