zoukankan      html  css  js  c++  java
  • 可变类型变量(列表、字典等)定为函数默认值时的陷阱

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

    可变类型变量列表测试:

    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]

      

  • 相关阅读:
    mysql 优化
    对象的特征
    对象的回收机制
    对象产生的过程
    python 内容查询小助手
    python笔记
    python安装MySQLdb模块
    python笔记
    python笔记
    定期删除备份文件,节省磁盘空间脚本
  • 原文地址:https://www.cnblogs.com/baihualin/p/10403942.html
Copyright © 2011-2022 走看看