Python函数的默认参数坑点解析

最近在开发的过程中,发现项目的代码中函数大量运用了默认参数,但是一些人在使用默认参数时忽略了其中的一些隐患。在这里予以解析。
比如下面的一段代码:

def test(v=[]):
    v.append(1)
    print id(v), v

test()
test()

上面代码的一个主要问题就是使用了可变类型list作为默认参数。如果你在使用test函数时默认传入一个list问题倒是不大,但是如果你使用默认的参数[],并且在函数内部更改了v的话,那么就会得到如下输出:

55916664 [1]
55916664 [1, 1]

可以看到,无论你调用多少次test函数,v的地址始终不变,并且它的大小会随着调用test的次数不断加一。
这说明,Python在解析函数的时候会为默认参数分配一个地址存储为一个匿名的变量,在使用默认参数的时候直接使用这个匿名变量。
所以我们在使用默认参数的时候,还是应当小心一些,尽量不要用可变类型对象作为默认参数。
其实不仅仅是可变类型,哪怕是不可变类型(int、float等),拿他们做默认参数Python也是这么处理的:

x=6
def test(v=x):
    print id(v), v

x=5
print id(x)
test()
test(x)

输出如下:

40467760
40467748 6
40467760 5

可以看到,x的地址为40467760,在解析test的时候,Python会为v的默认参数生成一个变量,它的值和x当时的值一样,地址为40467748。但是如果全局变量x改变后,这个默认变量的值是不会改变的。

原文地址:https://www.cnblogs.com/wickedpriest/p/13267701.html