为什么不用可变的list作为参数

如下代码:

def test_list(my_list=[]):
    my_list.append(1)
    return my_list
print(test_list())
print(test_list())
print(test_list())

Output:

[1]
[1, 1]
[1, 1, 1]

 

直观上讲,输出应都为 [1]。我们知道一个法则是不要用可变的变量作为参数, 可是为什么呢?

 

function 有个内置函数func_defaults能够显示默认的变量。

>>> test_list.func_defaults
([],)

可以看到函数test_list的func_defaults属性指向一个元组,这个元组有一个[] 的元素,即函数参数my_list的默认值。可错就错在,这个my_list指向那块区域是可变的。

 

执行一次函数test_list()后,再看看func_defaults指向的元组有没有发生变化。

>>> test_list()
[1]
>>> test_list.func_defaults
([1],)

可以看到my_list的默认值变成了[1]. 这是my_list 指向一个可变的list, 而且python函数默认是引用传递的, 在函数内部对my_list执行append操作的时候,同时也改变了my_list指向的func_defaults指向的那个元组的list。 下一次执行时,my_list默认值变成了([1],).

 

看一下python tutor

 

 

 

 

 如果函数确实需要接受一个list呢, 可以把my_list设为None。

def test_list(my_list=None):
    if not my_list:
        my_list = []
    my_list.append(1)
    return my_list

 

posted @ 2017-05-20 13:34  Haichao_cn_blog  阅读(867)  评论(0编辑  收藏  举报