请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

数量乘法实现的疑问

bobo老师,您好!请问在Vector数量乘法中,为什么把__mul__改成__rmul__就可以实现k的位置不同,代码里面好像看不出来?

正在回答 回答被采纳积分+3

2回答

提问者 公孙睿Python 2020-02-23 06:56:02

老师好!我就是区别不出这两个方法有什么不同?

0 回复 有任何疑惑可以回复我~
  • 如果你只定义了 __mul__,没有定义 __rmul__,运行这句话会出错:print("{} * {} = {}".format(3, vec, 3 * vec))。试试看删除 __rmul__ 的定义,看看运行 main 函数会发生什么?出错的原因就是,因为没有 __rmul__,程序不知道如何计算 3 * vec。
    回复 有任何疑惑可以回复我~ 2020-02-23 07:00:12
  • 同理,你可以把 __rmul__ 的定义修改成 return Vector([k * e for e in self]),然后删除 __mul__ 的定义(这样做,__rmul__ 的逻辑是独立的,不依靠__mul__)。现在,你的程序里只有 __rmul__ 的定义,没有 __mul__ 的定义了。再运行 main 函数 试试看?此时,运行这句话会出错:print("{} * {} = {}".format(vec, 3, vec * 3))。试试看?出错的原因就是,因为没有 __mul__,程序不知道如何计算 vec * 3。
    回复 有任何疑惑可以回复我~ 2020-02-23 07:03:04
  • 提问者 公孙睿Python 回复 liuyubobobo #3
    这个我大概明白,就是对__rmul__这个方法的逻辑不太明白,为什么写成 return self * k 就可以实现,可以写成 return k * self 吗?两者有什么不同?
    回复 有任何疑惑可以回复我~ 2020-02-23 07:04:14
liuyubobobo 2020-02-23 06:01:02

我不确定我是不是理解了你的问题。


我们不是把 __mul__ 改成了 __rmul__,而是 添加了 __rmul__ 方法。

__mul__ 定义了 self * k 是如何运算的;

__rmul__ 定义了 k * self 是如何运算的。


==========


在 main 函数中,运行 vec * 3 的过程,就会执行 Vector 类的 __mul__ 逻辑。


Vector 的 __mul__ 逻辑是这样的:

def __mul__(self, k):
    """返回数量乘法的结果向量:self * k"""
    return Vector([k * e for e in self])

这个逻辑已经很完整了,返回了一个新的 Vector 类的对象。这里,我相信你没有问题。


但是,在 main 函数中,计算 3 * vec 的时候,此时,这个 3 在 vec 的左边,不能执行 __mul__,需要执行 __rmul__,这就是我们写 __rmul__ 的意义。


__rmul__ 的逻辑是这样的:

def __rmul__(self, k):
    """返回数量乘法的结果向量:k * self"""
    return self * k


进入 __rmul__ 以后,就一句话,执行 return self * k

此时,为了计算这个 self * k,因为 k 在右边,所以又会调用 __mul__ 的逻辑,进入了这个函数:

def __mul__(self, k):
    """返回数量乘法的结果向量:self * k"""
    return Vector([k * e for e in self])


在 __mul__ 这个函数中,再次按照 __mul__ 的定义,创建了一个新的 Vector,返回了回去。


以上是整个执行过程。


==========


补充说明1:

def __rmul__(k, self) return __mul__ 的写法不对,因为语法不对。


补充说明2:

def __rmul__(self, k):
    """返回数量乘法的结果向量:k * self"""
    return self * k

这个 __rmul__ 函数本质其实就是在说,k * self 的运算结果,和 self * k 一样。


如果还不能理解,把 __rmul__ 写成这样也是正确的:

def __rmul__(self, k):    
    """返回数量乘法的结果向量:k * self"""
    return Vector([k * e for e in self])

如果你还不能理解,我也不知道要怎么解释了。。。


继续加油!:)

0 回复 有任何疑惑可以回复我~
  • 提问者 公孙睿Python #1
    老师好!我就是区别不出这两个方法有什么不同?
    回复 有任何疑惑可以回复我~ 2020-02-23 06:59:03
  • 提问者 公孙睿Python #2
    谢谢老师的指点,我大概明白了。同时又有了新的问题,就是程序在执行的时候,内部的原理是怎么样的?比如我调用的时候,写了两个向量相加,它怎么知道要调用的是__add__,而不是__sub__?
    回复 有任何疑惑可以回复我~ 2020-02-23 11:01:02
  • 提问者 公孙睿Python #3
    比如我写了一个加法的方法,def add(a, b): return  a + b,调用的时候,我输入 add(3, 4), 这里我就很明显的写了调用add()这个方法。而例子中,调用的时候,只是写了vec + vec2,它是怎么知道要掉用__add__方法的?
    回复 有任何疑惑可以回复我~ 2020-02-23 11:08:45
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信