关于 Python 的默认参数,有一个疑惑,请教大家![python3]

2017-01-19 16:07:31 +08:00
 palmers

代码如下:

def fun(l=None):
    if l is None:
        l = []
    l.append('append content')
    return l

这里当执行 l = [] 是不是就代表 l 已经指向了 一个空 list 了, 那不是同样会出现默认参数的记忆效果?

我想这里很有可能是我对 python 内存分配的原理不懂, 烦请大家帮我解释下, 谢谢大家啦!!

2443 次点击
所在节点    Python
4 条回复
thekoc
2017-01-19 16:17:29 +08:00
kindjeff
2017-01-19 16:22:08 +08:00
当然不会记忆啊,你试试这个
a=[]
b=[]
a.append(1)
这个时候 b 是[1]吗?
ipwx
2017-01-19 16:38:47 +08:00
Python 语言设计的一个规定,参数的默认值是对象而非一个表达式,不会每次重新执行,所以你在默认参数写 l=[] 才会导致 mutable 。

C++ 的规定正好相反,参数的默认值是一个表达式而非一个对象,每次调用都会重新执行这个表达式。
aragakiiyui
2017-01-20 16:47:29 +08:00
因为函数在 python 中也是一个对象,比如你举例的 fun 函数, func.__defaults__这个属性记录了函数的默认值 tuple ,你这个例子里面,这个 tuple 是(None, )。 假如你默认值指定了一个可变对象,比如空列表。 那么这个 tuple 里面存的值会是([], )。 这样就会导致你在代码中改变这个默认参数的时候(比如往这个列表中加了个元素 10 ),会影响 func.__defaults__相应的值---变成了([10], )。

所以要避免这种情况,函数的默认参数最好指定为不可变的对象。

你在函数体中进行 l = [], 等于将 l 这个变量名绑定了新的[], 这样对 func.__defaults__不会产生任何影响。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/335645

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX