为什么不能修改以前引用"None"的变量?



例如,

def function(data=None):
print(data,id(data))
if data is None:
data=[]
print(data,id(data))
data.append(1)
print("==================")
function()
function()
>> None 1781798096
[] 1780266168520
==================
None 1781798096
[] 1780266174856
==================

在第一次执行function()时,变量data引用一个"None"对象(id:1781798096(,在代码的第三行,现在data引用一个空列表对象(id:1780266168520(在第二次执行function时,data应该有id值1780266168520。但令人惊讶的是,当data引用"None"对象时,它给出了相同的值1781798096。

但是如果我们将默认参数更改为某个任意列表,例如 [0],

[0] 1780266149960
[0] 1780266149960
==================
[0, 1] 1780266149960
[0, 1] 1780266149960
==================

我们发现它给出了相同的 id 值。

所以我的问题是为什么我们不能修改以前引用"None"对象的变量,如果我们将默认参数设置为"None"和 [0],为什么会出现这种差异?

如果你问为什么dataid值最初是相同的,那么这是因为默认参数在定义函数时初始化一次,并保留在整个程序中。这也是"最不惊讶"和可变默认参数的原因。

重新分配data时,发生的情况只是它指向一个新对象(空列表(,并且该对象可能具有也可能不具有相同的id(REPL 会话经常重用相同ids的垃圾收集变量(。

None 是单例对象,因此不应创建 NoneType 的多个对象。(请注意,您可以创建单例类的多个对象(。在python中,你并不总是改变它所持有的值,你在对象上调用方法,修改它或创建新对象并分配对变量的引用。以前,它保存对 None 对象的引用,当您更改它时,它保留对其他对象的引用。同样,当你再次分配 None 时,python 初始化了引用值 None。

调用没有参数的函数,因此在输入function()时将其设置为None。 当你想保留data的值时,你需要返回data变量,然后在第二次调用中将其传递给function()

最新更新