Python 为什么可以';t以前提到的变量;无”;要修改吗?

Python 为什么可以';t以前提到的变量;无”;要修改吗?,python,function,parameters,nonetype,Python,Function,Parameters,Nonetype,比如说, 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 ===============

比如说,

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
表示第二次执行
function
时的空列表对象(id:1780266168520),
数据
预期具有id值1780266168520。但令人惊讶的是,当
data
引用“None”对象时,它给出了1781798096,这是相同的值

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

[0] 1780266149960
[0] 1780266149960
==================
[0, 1] 1780266149960
[0, 1] 1780266149960
==================
我们发现它给出了相同的id值


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

如果你问为什么
数据
id
值最初是相同的,这是因为默认参数在定义函数时初始化一次,并在整个程序中保持不变。这也是为什么会这样


数据
被重新分配时,所发生的只是它指向一个新对象(空列表),这个对象可能有也可能没有相同的
id
(REPL会话经常重用垃圾收集变量的相同
id

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

您调用的函数没有参数,因此在输入
function()
时,它被设置为
None

如果要保留
数据的值
,则需要返回
数据
变量,然后在第二次调用中将其传递给
函数()

您的问题毫无意义。您是否在问为什么局部变量在函数调用中不保留其值?@melpomene如果您将默认参数更改为任意列表,您将发现id值完全相同。当您将默认参数设置为“无”时,为什么会出现这种差异?我不明白您在说什么。
data
是一个局部变量,仅在单个函数调用的范围内;以前的任何函数调用都不会记住它。请记住,
id(None)
将始终为整个Python会话返回相同的id,分配给
None
的任何变量也将具有相同的id。如果使用
[0]
作为默认值,
如果数据为None
则永远不会为真,因此您永远不会为
数据
分配任何其他内容。因此,
data
总是引用同一个对象。当重新分配
data
时,它指向一个新对象([])。所以我猜
数据
不再指向“无”,不是吗?@Jin You是对的,每次赋值后它都指向不同的
[]
。@COLDSPEED那么如果它指向[],而不是“无”,为什么
数据
的id值与“无”的id值相同在第二次执行
函数后
?@Jin,因为
数据不是None
,所以
数据
不会被重新分配,所以您所要做的就是附加到相同的列表中。看见