减少使用位置参数
使用可选参数(*args)可以使方法看起来更清晰,减少视觉噪音。例如,你想要记录一些代码调试信息,如果使用固定参数,那么你的方法可能就像下面的示例一样接收两个参数:
如果你在调用这个方法时又不想给values传值,那么你就不得不传递一个空数组给方法,但是此时更好的处理方式是取消方法的第二个参数。在Python中你可以给第二个参数前面加一个星号(*)来解决这个问题。这样,第一个参数还是一个位置参数,是必填的,而它后面的参数是选填的,可以有多个,也可以没有。方法体并不需要做任何修改,只需要修改一下调用方式即可:
如果在调用log方法前,已经有了一个数组,此时可以使用*来传值:
使用可变数量参数时有两个问题:
- 第一个问题是,可变参数在被传递给方法前总是被转换成元组(tuple)。这就意味着,如果你调用这种方法时,传入的是一个生成器,那么Python会遍历生成器并生成一个元组。在生成元组的过程中可能会消耗一些内存,如果生成器过大,可能会导致程序崩溃。例如:
所以说使用*args的前提是输入参数的数量不大。理想状态是在调用这类方法时同时传递文本值和变量名(原文是:It’s ideal for function calls that pass many literals or variable names together. 我不知道我翻译的准确吗)。这样做的主要目的是方便开发人员以及提高代码可读性。
- 第二个问题是如果将来代码发生改变时,你不能够添加新的位置参数了,除非你去修改每一个调用这个方法的地方。如果你在方法定义中*args前面增加了位置参数,但是又没有修改方法调用,那么代码就会出现一些奇怪的问题。例如,按照以下方式修改log方法:
这里的问题就是,因为你没有给sequence传值,所以第二次调用log方法时传递给message参数的值是7。但是代码仍然能够执行下去,没有出现任何异常,所以调试起来也很困难。为了避免这类问题的出现,当你需要拓展方法时,应该使用关键字参数。
其它注意事项
- 方法可以接收一个可变的位置参数;
- 可以使用星号将一个序列中的值传递给方法;
- 使用星号传递生成器可能会造成内存溢出;
- 为方法添加新的位置参数可能会引入难以发现的bug.