python3函数默认参数的坑

在定义一个函数时,有的时候会添加默认参数。如

def fun(a = 0):
    pass

但默认参数倘若不注意会跳进一个较大的坑,如

## 设置个标签 flag
def fun(L = []):
    L.append(1)
    return L

a = fun()
b = fun()

问此时a, b的值是什么。倘若认为此时的 L 为局部变量,则很容易答出a = [1], b = [1],但是应该是 a = [1, 1], b = [1, 1]
这一特性在Python的官方文档中有特别说明,位置为:入门教程/4.7.1默认参数值

文档的大意为:
默认参数在函数被定义的同时也被定义。
举个例子更加好理解:

i = 5

def fun(num = i):
    print(num)

i = 6

fun()

#=====run=====
5

对前面flag中的函数可以这样改编

l = []
def fun(L = l):
    L.append(1)

    return L

a = fun()
b = fun()

在这里将上面默认参数的值,也就是空列表具体赋给变量 l(小写L)。

接下来是python几个特性的融合:
首先默认参数在函数被定义的时候被定义,所以 L 在函数被定义的时候得到空列表的指针。
但是由于在python中可变对象的传递都是传递指针,所以在两次函数调用后 l, L, a, b 四个变量指向的都是同一个内存地址。也就是:
在这里插入图片描述

那么无论是谁对这片内存空间进行操作,四个指向此内存空间的变量都会发生改变(关于可变对象的特性建议学习c语言的指针进行更加深刻的理解,在此之前可以当作知识点背诵)

如果查看 l 的值可以发现 l 的值也和a, b一样。
在这里插入图片描述
那么回到 flag 里的函数

def fun(L = []):
    L.append(1)

    return L

a = fun()
b = fun()

道理是完全一样的:
首先默认参数在函数被定义的时候定义,所以 python 在内存中创建了一个空列表,并且让 L 指向空列表
调用两次函数后 L, a, b 指向的是同一片内存空间

在这里插入图片描述
不同的是因为并没有在全局变量中定义一个变量(如 l)指向这片空间,所以在主函数中是无法直接访问这片空间的。

备注:虽然说 L 也是指向这片内存空间的,但是因为 L 的作用域只在函数内部,所以在主函数中是没办法通过 L 访问这片内存空间。但是可以在函数内部指向此内存空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值