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

29
我写了一个Python类来表示向量(作为练习),但我在扩展内置运算符时遇到了问题。我为向量类定义了一个__mul__方法。问题是,在表达式x * y中,解释器调用x的__mul__方法而不是y的方法。
因此,vector(1, 2, 3) * 2返回向量<2, 4, 6>,就像应该做的那样;但是2 * vector(1, 2, 3)会创建一个TypeError,因为内置int类不支持与我定义的向量相乘。
我可以通过编写一个新的乘法函数来解决这个问题。
def multiply(a, b):
    try:
        return a * b
    except TypeError:
        return b * a

但这将需要重新定义我想要与我的自定义类一起使用的每个函数。

有没有一种方法可以使内置函数正确处理这个问题?

2个回答

36
如果您希望在不同类型之间实现可交换性,您需要实现__rmul__()。如果已经实现,它将像所有__r*__()特殊方法一样被调用,如果操作否则会引发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() '''

Python如何知道调用Foo.__rmul__而不是另一个对象的__mul__ - user166390
2
它尝试使用左侧的__mul__,如果找不到,则查找右侧的__rmul__ - Karl Knechtel
4
在Python中,当使用乘法运算符时,首先调用对象的__mul__方法。但是,如果该方法不存在或返回NotImplemented,则Python将调用另一个对象的__rmul__方法来尝试进行乘法运算。(请注意,如果__mul__引发异常,则不会调用__rmul__方法。) - Ethan Furman

3

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