2017-08-26 54 views
-4

例如,为什么不能修改先前提到“无”的变量?

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指“无”对象(ID:1781798096)按代码的第三行,现在data指空的列表对象(ID :1780266168520)在的function秒执行,data预计将有值1780266168520.的ID,但出人意料的是,它给出1781798096这是当data所指的“无”对象相同的值。

但是,如果我们改变默认的参数有些武断名单,说[0],

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

,我们发现,它给了相同的ID值。

所以我的问题是,为什么我们不能修改这在以前被称为“无”对象的变量,为什么发生这样的区别,如果我们设置默认参数设置为“无”,[0]?

+1

你的问题是没有意义的。你在问为什么局部变量不能在函数调用中保留它们的值? – melpomene

+0

@melpomene如果您将默认参数更改为某个任意列表,您将发现id值完全相同。为什么在将默认参数设置为“无”时出现这种差异? – Jin

+0

我不明白你在说什么。 – melpomene

回答

3

如果你问为什么dataid值最初是相同的,那是因为默认参数在定义函数时被初始化一次,并保留在整个程序中。这也是"Least Astonishment" and the Mutable Default Argument的原因。

data重新分配,所发生的一切是它指向一个新的对象(空单),这个对象可能会或可能不会有相同的id(REPL会话经常重复使用的垃圾收集变量相同ids) 。

+0

当'data'被重新分配时,它指向一个新的对象([])。所以我猜'数据'不再指向'无',不是吗? – Jin

+0

@Jin你说得对,它在每次赋值后指向一个不同的[]'。 –

+0

@COLDSPEED那么如果它指向[]而不是“None”,为什么数据的id值与第二次执行'function'后的id值是“None”? – Jin

0

都不是一个单独的对象,所以你不应该创建NoneType的多个对象。 (请注意,您可以创建单个类的多个对象)。在python中,你并不总是改变它所持有的值,你可以在对象上调用方法,修改它,或者创建新的对象并为变量赋值。以前,它在保存对None对象的引用时,将其更改为其对其他对象的引用。同样当你再次分配None时,参考None的python初始化参考值。

0

您调用函数不带参数,所以在进入function()当它被设置为None。 当你想保留的data值,你需要将它在第二次调用返回data变量,然后传递给function()

相关问题