美文网首页数据蛙数据分析每周作业
Python易错知识点之默认参数的使用

Python易错知识点之默认参数的使用

作者: 米兔妮妮 | 来源:发表于2019-01-06 08:00 被阅读3次

    一、问题描述:

    例如,定义一个函数,传入一个list,添加一个end再返回:

    def add_end(l=[]):
        l.append('end')
        return l
    

    1、不使用默认参数调用时,

    print add_end([1, 2])
    

    运行结果如下:

    [1, 2, 'end']
    

    没有问题。

    2、使用默认参数时,

    print add_end()
    print add_end()
    

    运行结果如下:

    ['end']
    ['end', 'end']
    

    可见,第一次调用时返回结果正确,第二次调用时返回结果错误。

    二、错因分析:

    首先明确,默认参数也是一个变量,python函数在定义的时候,默认参数l的值就被计算出来了,它存储一个空列表[ ]的内存地址(注:python使用引用语义,即python变量保存的是值的引用,采用这种方式,变量所需的存储空间大小一致,因为变量只是保存了一个引用),即它指向空列表[ ],默认参数l存储的这个内存地址不会在该函数被调用的时候再被计算。

    调用该函数时若使用默认参数,会对默认参数进行修改,而实际修改的是默认参数指向的列表,默认参数L中存储的仍然是该列表的内存地址。第一次使用默认参数后默认参数指向的列表已经不再为空。

    简而言之,就是默认参数的值在定义的时候被计算,调用的时候不会再次被计算。所以每一次函数调用对默认参数的修改都会影响下一次函数调用。

    三、解决办法

    使默认参数指向不变对象。例如:

    def add_end2(l=None):
        if l is None:
            l = []
    
        l.append('end')
        return l
    

    使用默认参数:

    print add_end()
    print add_end()
    

    运行结果如下:

    ['end']
    ['end']
    

    python不变对象是指该对象在内存中的值不能被改变。当改变某个变量的值时,由于该变量指向的值为不可变对象,会在内存中重新开辟一个新的地址,存储新的值,然后将变量指向这个新的值。原来的内存中的值并不会发生变化。python不变类型包括数值类型(int和float)、字符串(string)、元组(tuple)、None。

    python可变对象即该对象在内存中的值可以被改变。变量改变后,实际其所指向的值直接发生改变。python可变类型包括列表(list)、字典(dict)、集合(set)。

    设计不可变对象的好处:
    1、不变对象一旦创建,其内部的数据就不能修改,这样就减少了由于修改数据导致的错误。
    2、由于对象不变,在多任务环境下同时读取不变对象不需要加锁。若对象可变,在多任务环境下读取对象时必须加锁,以防止在读取过程中其它任务对变量进行修改。

    牢记:使默认参数指向不变对象。

    参考:

    https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001374738449338c8a122a7f2e047899fc162f4a7205ea3000

    相关文章

      网友评论

        本文标题:Python易错知识点之默认参数的使用

        本文链接:https://www.haomeiwen.com/subject/wkbjrqtx.html