21.3_问题1:左项为float或int的情况
21.3 问题1:左项为float或int的情况
当 是Variable实例时,使用现在的DeZero可以正确运行代码 。但是,运行代码 会出错。在实际运行时,系统提示的错误信息如下所示。
运行结果
TypeError: unsupported operand type(s) for*: 'float' and 'Variable'
要想了解出现如上错误的原因,可以看看执行代码 时错误发生的过程。在执行代码 时,系统会按照以下步骤进行处理。
尝试调用在运算符*左侧的2.0的__mul__方法
2.0是浮点数,__mul__方法没能得到实现
然后尝试调用在 *运算符右侧的 x (Variable) 的特殊方法
由于 在运算符的右侧,所以尝试调用的是__rmul__方法(而不是__mul__)
但是Variable实例没有实现__rmul__方法
这就是错误发生的过程。重点是,对于*这种有两个操作数项的运算符,要调用的特殊方法取决于操作数项是右项还是左项。如果是乘法运算,那么对左项调用__mul__方法,对右项调用__rmul__方法。
基于以上分析,我们知道只要实现__rmul__方法就可以解决这个问题。这时,参数会按照图21-1的方式传给__rmul__方法。

图21-1 向__rmul__方法传递参数的示意图
如图21-1所示,在__rmul__(self, other)的参数中,self对应自己,即x, other对应另一个操作数项2.0。不过乘法运算的左右项即使交换,结果也不会发生改变。比如 和 的结果相同。因此,对乘法,我们没有必要区分左右项。对加法也是如此,所以针对+和*,只要设置以下4个特殊方法即可。
steps/step21.py
Variable._add_ $=$ add
Variable._radd_ $=$ add
Variable._mul_ $=$ mul
Variable._rmul_ $=$ mul现在可以任意组合float和int进行计算了。下面是一个使用示例。
steps/step21.py
$\begin{array}{rl} & {\mathrm{x = V�ariable(np.array(2.0))}}\\ & {\mathrm{y = 3.0*x + 1.0}}\\ & {\mathrm{print(y)}} \end{array}$
运行结果 variable(7.0)这样就可以将Variable实例与float及int一起使用了。最后还有一个问题需要解决。