可变类型变量在函数默认值中的一坑,以后大家记得绕着走,话不多说,上代码!

可变类型变量列表测试:

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]

  

02-20 06:10