更改自定义类中__add __,__ mul__等方法的操作顺序

nlu*_*igi 6 python class operator-overloading object

我有一个矢量类:

class Vector:
    def __init__(self, x, y):
        self.x, self.y = x, y
    def __str__(self):
        return '(%s,%s)' % (self.x, self.y)
    def __add__(self, n):
        if isinstance(n, (int, long, float)):
            return Vector(self.x+n, self.y+n)
        elif isinstance(n, Vector):
            return Vector(self.x+n.x, self.y+n.y)
Run Code Online (Sandbox Code Playgroud)

哪个工作正常,即我可以写:

a = Vector(1,2)
print(a + 1) # prints (2,3)
Run Code Online (Sandbox Code Playgroud)

但是,如果操作顺序颠倒,则失败:

a = Vector(1,2)
print(1 + a) # raises TypeError: unsupported operand type(s)
             #                   for +: 'int' and 'instance'
Run Code Online (Sandbox Code Playgroud)

我理解错误:一个的加入int对象的Vector,因为我没有在定义它的对象是未定义int类.有没有办法解决这个问题而不在类int(或父int类)中定义它?

mem*_*tum 7

你还需要定义 __radd__

有些操作不一定像这样评估a + b == b + a,这就是Python定义addradd方法的原因.

更好地解释自己:它支持"int"没有定义+具有class Vector实例作为操作一部分的操作这一事实.因此,向量+ 1与1 +向量不同.

当Python试图查看该1.__add__方法可以执行的操作时,会引发异常.Python继续寻找Vector.__radd__操作来尝试完成它.

在OP的情况下,评估是真实的,并且足够__radd__ = __add__

class Vector(object):

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

    def __str__(self):
        return '(%s,%s)' % (self.x, self.y)

    def __add__(self, n):
        if isinstance(n, (int, long, float)):
            return Vector(self.x+n, self.y+n)
        elif isinstance(n, Vector):
            return Vector(self.x+n.x, self.y+n.y)

    __radd__ = __add__


a = Vector(1, 2)
print(1 + a)
Run Code Online (Sandbox Code Playgroud)

哪个输出:

(2,3)
Run Code Online (Sandbox Code Playgroud)

这同样适用于所有类似数字的操作.