可变数据类型作为初始化形参 / Mutable Parameter as Init Formal-para
由于在Python中,没有类似C语言的static静态参数,因此当一个函数需要一个只初始化一次的参数时,通常会在函数外部进行初始化操作,较为不便。
但是在Python中,可以利用可变参数作为函数的形参默认值来实现这一功能,
完整代码
1 # n is mutable 2 def foo_1(x, n=[]): 3 print(id(n)) 4 n += [x] 5 print(id(n)) 6 print(n) 7 8 foo_1(2) 9 foo_1(3) 10 foo_1(5) 11 12 print(20*‘-‘) 13 # n is immutable 14 def foo_2(x, n=()): 15 print(id(n)) 16 n += (x, ) 17 print(id(n)) 18 print(n) 19 20 foo_2(2) 21 foo_2(3) 22 foo_2(5)
分段解析
首先,定义了一个函数,其中形参n的默认值为可变类型的list,在函数中,首先查看n的id,随后对n进行操作,添加传入的参数值,再次查看n的id以及n的值。
1 # n is mutable 2 def foo_1(x, n=[]): 3 print(id(n)) 4 n += [x] 5 print(id(n)) 6 print(n) 7 8 foo_1(2) 9 foo_1(3) 10 foo_1(5)
利用3个数进行测试,输出结果
55021192 55021192 [2] 55021192 55021192 [2, 3] 55021192 55021192 [2, 3, 5]
从输出的结果中可以看到,3次函数调用的n都是同一个id,同时,n的值也并未在每次函数进入时重新初始化,也就是说,参数n在每次调用时都会进行重指向,指向初始化的值的地址。但是,由于n指向的是个可变的列表,因此当n所指向的值被改变了之后,n再次重指向该地址时,该地址的值即是改变之后的值。
接下来利用不可变的元组进行测试,同样进行上面类似的操作。
1 # n is immutable 2 def foo_2(x, n=()): 3 print(id(n)) 4 n += (x, ) 5 print(id(n)) 6 print(n) 7 8 foo_2(2) 9 foo_2(3) 10 foo_2(5)
输出结果
4456520 52583336 (2,) 4456520 16619168 (3,) 4456520 52583336 (5,)
从最终的输出可以看到,与列表不同的是,每次输出的元组都是该次传入的元素。通过查看元组的id可知,由于元组是不可变的,因此每次进行添加操作时,实际上都是将元组进行了重新指向,而原本的空元组并未被修改,所以,再次进入函数时,参数n重新指向空元组的id,也就将值进行了重新的初始化。