用户定义的 __mul__ 方法不可交换
Posted
技术标签:
【中文标题】用户定义的 __mul__ 方法不可交换【英文标题】:User defined __mul__ method is not commutative 【发布时间】:2011-10-31 01:29:17 【问题描述】:我在 Python 中编写了一个表示向量的类(作为练习),但在扩展内置运算符时遇到了问题。
我为向量类定义了一个__mul__
方法。问题是在表达式 x * y
中,解释器调用 x 的 __mul__
方法,而不是 y。
所以 vector(1, 2, 3) * 2
返回一个向量 就像它应该的那样;但是2 * vector(1, 2, 3)
创建了一个 TypeError,因为内置的 int 类不支持与我的用户定义的向量相乘。
我可以通过简单地编写一个新的乘法函数来解决这个问题
def multiply(a, b):
try:
return a * b
except TypeError:
return b * a
但这需要重新定义我想与我的用户定义类一起使用的每个函数。
有没有办法让内置函数正确处理这个问题?
【问题讨论】:
【参考方案1】:如果您想要不同类型的交换性,您需要实现__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__
?
它尝试使用左侧的__mul__
,如果找不到,则查找右侧的__rmul__
。
@pst,Python 首先调用__mul__
,但如果它不存在或者返回NotImplemented
,那么Python 调用另一个对象的__rmul__
。 (请注意,如果 __mul__
引发 execption,__rmul__
将不被调用。【参考方案2】:
相信你在找__rmul__
【讨论】:
以上是关于用户定义的 __mul__ 方法不可交换的主要内容,如果未能解决你的问题,请参考以下文章