【问题标题】:Global variable seems by be corrupted by executing a recursive code全局变量似乎被执行递归代码破坏了
【发布时间】:2020-12-12 10:04:09
【问题描述】:

我是 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, 2, 4] OK here
  =? [1, 3, 4] <<< Here has the next global value. Why? Global Var should't do that!

set: [1, 3, 4]
...

知道为什么 globVar 似乎会受到递归上下文的影响吗?

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

谢谢你们!

【问题讨论】:

    标签: python variables recursion scope global


    【解决方案1】:

    变量XglobVar指的是相同单列表。所以当你这样做时:

    X[Y] = i
    

    您正在改变同一个列表。你不妨这样写:

    globVar[Y] = i
    

    效果完全一样。

    因此,您应该创建一个 列表。例如,您可以这样做:

    globVar = X[:]
    

    【讨论】:

      【解决方案2】:

      看下面:

      >>> s = set([1,2,3])
      >>> x = s
      >>> s.add(4)
      >>> s
      {1, 2, 3, 4}
      >>> x
      {1, 2, 3, 4}
      

      分配x = s 不会创建分配给s 的集合的副本。事实上,s 分配了什么?除了 reference 或指向该集合所在的内存位置的指针之外什么都没有。因此,赋值x = s 只是复制引用,使x 指向s 指向的同一集合。现在,当您修改s 所指的集合时,您正在修改x 所指的集合。

      但是在这里您正在创建一个新集合,即s 指向的集合的副本,并将指向该新集合的指针分配给x

      >>> s = set([1,2,3])
      >>> x = s.copy()
      >>> s.add(4)
      >>> s
      {1, 2, 3, 4}
      >>> x
      {1, 2, 3}
      

      这就是 Python 中对象分配的工作方式,无论这些对象是集合、列表、字典等还是您自己定义的类实例。

      【讨论】:

        【解决方案3】:

        总是检查是否

        globVar is X
        

        如果你尝试一下,你会发现globVarX 是指向内存中相同信息的指针。

        如果您更改 globVarX 也会更改。 如果您希望避免这种情况并为两者提供单独的副本,则必须这样做

        globVar = X[:]
        

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

        【讨论】:

          猜你喜欢
          • 2019-08-07
          • 2020-02-22
          • 1970-01-01
          • 2022-01-08
          • 2022-01-04
          • 1970-01-01
          • 1970-01-01
          • 2015-05-03
          • 1970-01-01
          相关资源
          最近更新 更多