通过执行递归代码,全局变量似乎已损坏

问题描述

我是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似乎受到递归上下文的影响吗?

我希望它的值只是最后一个值集。 但这不是打印输出显示的。

谢谢你们!

解决方法

变量XglobVar指的是相同单个列表。因此,当您这样做时:

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

如果您尝试查看globVarX是指向内存中相同信息的指针。

如果您更改globVar,则X也将被更改。 如果您希望避免这种情况,并为二者分别使用副本,则必须

globVar = X[:]

现在globVar is X为假,您可以安全地更改其中一个而不会影响另一个。