用户自定义的__mul__方法不满足交换律

29 投票
2 回答
14461 浏览
提问于 2025-04-16 23:59

我写了一个类来表示向量(这是我练习的一个项目),但是在扩展内置运算符时遇到了一些问题。

我为这个向量类定义了一个 __mul__ 方法。问题是,在表达式 x * y 中,解释器会调用 x 的 __mul__ 方法,而不是 y 的。

所以当我写 vector(1, 2, 3) * 2 时,它会返回一个向量 <2, 4, 6>,这正是我想要的;但是当我写 2 * vector(1, 2, 3) 时,就会出现一个类型错误,因为内置的整数类不支持和我自己定义的向量相乘。

我可以通过简单地写一个新的乘法函数来解决这个问题

def multiply(a, b):
    try:
        return a * b
    except TypeError:
        return b * a

但这样的话,我就得重新定义每一个我想和我自己定义的类一起使用的函数。

有没有办法让内置函数正确处理这个问题呢?

2 个回答

3

我想你是在寻找 __rmul__ 这个东西。

36

如果你想要实现不同类型之间的可交换性(也就是不管顺序如何结果都一样),你需要实现一个叫做 __rmul__() 的方法。如果你实现了这个方法,当你进行运算时,如果原本会出现 TypeError(类型错误),这个方法就会被调用。需要注意的是,这个时候传入的参数顺序是反过来的:

class Foo(object):
    def __mul_(self, other):
        ''' multiply self with other, e.g. Foo() * 7 '''
    def __rmul__(self, other):
        ''' multiply other with self, e.g. 7 * Foo() '''

撰写回答