默认参数最好不为可变对象
本帖最后由 一个账号 于 2021-1-5 22:25 编辑在之前写的一个项目中,就遇到这个错误。
在传递默认参数时,新手很容易遇到这个错误。
这个错误是什么呢?我们来看一个例子:
>>> def func(va, li=[]):
li.append(va)
print(li)
>>> func("A")
['A']
>>> func("B", ["C", "D"])
['C', 'D', 'B']
>>> func("E")
--------- 隐藏 ---------
>>>
你们猜猜最后输出的是什么呢?
>>> def func(va, li=[]):
li.append(va)
print(li)
>>> func("A")
['A']
>>> func("B", ["C", "D"])
['C', 'D', 'B']
>>> func("E")
['A', 'E']
>>>
Python 中的 def 语句在每次执行的时候都初始化一个函数对象,这个函数对象就是我们要调用的函数,
可以把它当成一个一般的对象,只不过这个对象拥有一个可执行的方法和部分属性。
对于参数中提供了初始值的参数,由于 Python 中的函数参数传递的是对象,
也可以认为是传地址,在第一次初始化 def 的时候,会先生成这个可变对象的内存地址,
然后将这个默认参数 li 会与这个内存地址绑定。在后面的函数调用中,如果调用方指定了新的默认值,
就会将原来的默认值覆盖。如果调用方没有指定新的默认值,那就会使用原来的默认值。
============================================分割线============================================
在这个帖子中顺便也写一下最近发现的一个有趣的事情
来看一个简单的例子:
li =
print(li)
执行一下,和我们的预期一样,会抛出索引错误:
IndexError: list index out of range
但是大家来看看这个例子:
li=
print(li)
最后会输出一个空列表
[] 真不错{:10_256:} 可以可以{:10_275:} 那么,避免这个问题的方法是什么呢?{:5_99:} 真可以{:10_275:} crisfo 发表于 2021-3-14 16:26
那么,避免这个问题的方法是什么呢?
这个完全 是因为你列表中没有这么长的字符,不需要避免,按照自己列表的长度,来截取字符串就可以了 程序员不秃 发表于 2021-3-14 17:21
这个完全 是因为你列表中没有这么长的字符,不需要避免,按照自己列表的长度,来截取字符串就可以了
不好意思,没表述清楚,我说的是 li = [] 的问题
页:
[1]