问题描述
我是Python的新手。我不知道为什么执行递归代码会损坏全局变量。
globVar = []
def explore(X,Y):
global globVar
globVar = X
print()
print("set: "+str(X)) # This is the only place where the global variable is set
for i in range(1,5):
X[Y] = i
if Y < 2:
print(" =? " + str(globVar) + " <<< Here has the next global value. Why? Global Var should't do that!")
explore(X,Y + 1)
print(" =? " + str(globVar) + " OK here")
# Launch recursive exploration
explore([1,1,1],0)
...
set: [1,2,4]
=? [1,4] OK here
=? [1,3,4] <<< Here has the next global value. Why? Global Var should't do that!
set: [1,4]
...
您知道为什么globVar似乎受到递归上下文的影响吗?
谢谢你们!
解决方法
变量X
和globVar
指的是相同单个列表。因此,当您这样做时:
X[Y] = i
您正在变异相同的单个列表。您可能还写了:
globVar[Y] = i
效果完全一样。
因此,您应该创建一个 new 列表。例如,您可以这样做:
globVar = X[:]
,
查看以下内容:
>>> s = set([1,2,3])
>>> x = s
>>> s.add(4)
>>> s
{1,3,4}
>>> x
{1,4}
分配x = s
不会为分配给s
的集合创建副本。实际上,为s
分配了什么 ?除了 reference 或指向该集合所在的内存位置的指针。因此,分配x = s
只是将引用复制为x
指向s
指向的同一集合。现在,当您修改s
所指的集合时,您正在修改x
所指的集合。
但是在这里,您要创建一个新集合,即s
所指向的集合的副本,并将指向该新集合的指针分配给x
:
>>> s = set([1,3])
>>> x = s.copy()
>>> s.add(4)
>>> s
{1,3}
无论对象是集合,列表,字典等还是您自己定义的类实例,这都是Python中对象分配的工作方式。
,始终检查是否
globVar is X
如果您尝试查看globVar
和X
是指向内存中相同信息的指针。
如果您更改globVar
,则X
也将被更改。
如果您希望避免这种情况,并为二者分别使用副本,则必须
globVar = X[:]
现在globVar is X
为假,您可以安全地更改其中一个而不会影响另一个。