Python笔记--默认参数最大的“坑”

来源:互联网 发布:大数据风控体系 编辑:程序博客网 时间:2024/06/06 00:38

日期:20170915


资料:
1、https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431752945034eb82ac80a3e64b9bb4929b16eeed1eb9000


Python中使用默认参数有很多好处,但是也有坑。而最大的“坑”,在这里提醒一下。

我们先定义一个函数,可传入一个默认参数list,list添加一个END后返回。
测试代码如下,

#!/usr/bin/python#-*- coding: utf-8 -*-def add_end(list=[]):        list.append('END')        return listprint("例1:")print("call add_end(1, 2, 3)")print( add_end([1, 2, 3]) )print   print("例2:")print("call add_end(\"x\", \"y\", \"z\")")print( add_end(["x", "y", "z"]) )print("上面两个例子不会出问题")printprint("试试调用两次add_end不带参数")print("例3:")print("call add_end()")print( add_end() )printprint("例4:")print("call add_end() again")print( add_end() )print("例4结果不是预期的")

运行

[penx@ali01 python2]$ ./test.py例1:call add_end(1, 2, 3)[1, 2, 3, 'END']例2call add_end("x", "y", "z")['x', 'y', 'z', 'END']上面两个例子不会出问题试试调用两次add_end不带参数例3call add_end()['END']例4call add_end() again['END', 'END']例4结果不是预期的[penx@ali01 python2]$

运行结果的倒数第3行(18行),输出了两个’END’,显然不是我们预期的。

原因解释如下,
因为默认参数list在函数定义时默认分配特定对象(叫它A吧),若每次不传入list值,那么list都会默认引用该对象A。
当对象A是可变对象时,如果A值改变,默认参数list引用对象还是引用A,那么list值就会跟着对象A改变。

所以,定义默认参数要牢记一点:默认参数最好(必须也不为过)指向不变对象。

如果想修改上面的例子,可以这样,

def add_end(list=None):    if list is None:        list=[]    list.append("END")    return list

引想

当看见上面相关知识点时就在想,
学习Python前面说变量的时候,都会给出以下例子,

#!/usr/bin/pythona=123b=aa=555print(a)

或者,

#!/usr/bin/pythona=123print aa="Hello"print a

来说明变量和对象的关系。
不清楚变量和对象关系的同学,可以查相关知识点,或者看我的一篇博客,

http://blog.csdn.net/ipenx/article/details/77987193#t2

然后,注意到多数说的只是简单的举例,变量引用不变对象
而可变对象很少有说,所以我测试一下,

当可变对象的值改变时,变量引用不变,变量值也会改变。

详情可看我的测试,

NULL(还没写)

原创粉丝点击