可变类型变量在函数默认值中的一坑, 以后大家记得绕着走, 话不多说, 上代码!
可变类型变量列表测试:
- 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]
来源: https://www.cnblogs.com/baihualin/p/10403942.html