12.1_第1项改进:使函数更容易使用

12.1 第1项改进:使函数更容易使用

在上一个步骤,我们使用Add类进行了计算。图12-1左侧是当时编写的代码。


图12-1 当前代码(左)和改进后的代码(右)

如图12-1左侧的代码所示,目前Add类的参数归并到了列表中,结果以元组的形式返回。不过图12-1右侧的代码更加自然:不将参数归并到列表,

而是直接将参数传递给 Add 类,结果也直接作为变量返回。第 1 项改进就是想办法写出这样自然的代码。

下面着手进行修改。我们要修改Function类。下面的阴影部分是对之前的代码所做的修改。

class Function: def__call__(self,\*inputs):#  $①$  添加星号 xs=[x.data for x in inputs] ys= self.forward(xs) outputs  $\equiv$  [Variable(as_array(y))for y in ys] for output in outputs: output.set creator(self) selfinputs  $\equiv$  inputs self.output  $\equiv$  outputs #  $②$  如果列表中只有一个元素,则返回第1个元素 return outputs if len(outpu5)  $\rightharpoondown$  1 else outputs[0]

首先看②处。这行代码在outputs只有一个元素时返回的是该元素,而不是一个列表。这意味着如果函数的返回值只有一个,那么这个变量将被直接返回。

接下来看①处。在定义函数时,我们在参数前添加了一个星号。这样就能在不使用列表的情况下调用具有任意个参数(可变长参数)的函数。我们从下面的示例可以很清楚地看出可变长参数的用法。

>>> def f(*x):
    ...
    print(x)
>>> f(1,2,3)
(1,2,3)
>>> f(1,2,3,4,5,6)
(1,2,3,4,5,6)

如上面的代码所示,如果在定义函数时给参数加上星号,那么在调用函

数时,所有参数就能以带星号的形式被一次性拿到。在对代码做上述修改之后,DeZero的函数类(Add类)可以按照下面的方式使用。

$\mathbf{x}\theta =$  Variable(np.array(2))   
x1  $=$  Variable(np.array(3))   
f  $=$  Add()   
y  $=$  f(x0,x1)   
print(y.data)

运行结果

5

这种编写方式对使用Add类的人来说更自然。到这里我们就完成了第1项改进,下面开始进行第2项改进。