Python_Tips[5] -> 可变数据类型作为初始化形参

可变数据类型作为初始化形参 / 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)
View Code

分段解析

首先,定义了一个函数,其中形参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,也就将值进行了重新的初始化。

原文地址:https://www.cnblogs.com/stacklike/p/8227666.html