可变类型变量在函数默认值中的一坑,以后大家记得绕着走,话不多说,上代码!
可变类型变量列表测试:
def abc(a=[]): a.append(123) print(a) abc() abc()
此时大家可能觉得应该输出如下内容:
[123]
[123]
其实不然,实际情况如下:
[123]
[123, 123]
那换另一个可变类型变量字典试下呢?
import random def abc(a={}): a[random.randint(1, 5)] = '123' print(a) abc() abc()
此时大家可能觉得应该输出如下内容:
{随机值: '123'} {随机值: '123'}
其实不然,实际情况如下:
{2: '123'} {2: '123', 3: '123'}
那么换成不可变类型变量会是怎样的呢?那么拿字符串来举例:
def abc(a=''): a = a + '1' print(a) abc() abc()
按照上面的惯性大家可能会以为输出结果为下面这样:
1 11
其实不然,实际情况如下:
1 1
总结:
1、表象:在python中可变类型变量作为默认值赋给函数时,多次调用该函数实际只初始化一次,这看起来好像是个bug。
2、本质:在python中对不可变类型(比如字符串)进行修改后其实不是对原本的值进行了更改(不可变类型之所以叫不可变类型就是值是固定的,不可修改),而是又开辟了一块新内存来新创建了一个值,然后再将变量指向这个新值的内存地址
def abc(a=[]): ===>假设此处空列表位于内存0x00001111 a.append(123) ===>将内存0x00001111的值增加了一个“123” print(a) abc() abc() ====>第二次调用时a的默认值其实还是原来的空列表内存处的值,即0x00001111,只不过此时该值增加了一个“123” def abc(a=''): ===>假设此处空列表位于内存0x00001111 a = a + '1' ===>由于字符串为不可变类型,故此处其实是将a指向了另外一个内存空间,假设为0x00002222,而在0x00002222处存放了一个"1" print(a) abc() abc() ====>第二次调用时a的默认值其实还是原来的空字符串内存处的值,即0x00001111,由于上一次变化是将a指向了另外一个值,所以此处的值还为空字符串
如需要可变类型变量作为默认值时可以采用如下方法:
def abc(a=None): a = [] a.append(123) print(a) abc() abc()
输出结果为:
[123]
[123]