在某些情况下,Python 2.6会自动将函数定义中的变量全局转换吗?为什么?

时间:2011-04-20 21:53:19

标签: python debugging global-variables issue-tracking local-variables

我绝对傻到为什么会发生以下情况:

这是我的代码:


def add_one(array):

    new_array = array
    length = len(array)

    for i in range(length):

        new_array[i] = new_array[i]+1


    return new_array

x = [1,2,3,4,5];
y = add_one(x)

print x

print y

结果如下:

[2, 3, 4, 5, 6]

[2, 3, 4, 5, 6]

我不明白为什么x会改变。

我的推测: 不知何故,x作为函数add_one的全局变量给出。我包含'new_array = array',这样如果数组不知何故是全局变量x,x就不会被改变。但是,当'new_array = array'被执行时,不知何故new_array也变成了全局变量x。我写了一个替代版本的函数add_one,它没有给我带来问题:


def add_one(array):

    new_array = []
    length = len(array)

    for i in range(length):
        new_array.append(array[i]+1)

似乎如果局部变量(即数组)是由函数中的索引编辑的,那么它相对于作为该函数输入的全局变量会变为全局变量吗?

我不知道发生了什么事。任何解释都将受到高度赞赏。

4 个答案:

答案 0 :(得分:6)

当你说new_array = array时,你没有复制数组,你只是在为数组创建另一个名称。这两个名称仍适用于同一阵列。

要制作副本,最简单的方法是使用切片:new_array = array[:]

答案 1 :(得分:4)

对于模糊的读者来说,没有什么是全球性的。 array仍然是一个完全正常的局部变量。但它是一个参考,因为Python中的所有东西(好吧,至少每个名字)都是一个参考:

  • add_one(x)传递引用(不像C ++中的引用,更像是指针 - 如果其中任何一个对您来说意味着什么)到xadd_one
  • new_array = array只会复制该引用
  • 没有发生复制,所有这些名称都指向同一个对象!

这意味着在arrayadd_one调用方法修改了调用者的同一个对象x,指的是 - 重新分配array({{1}只会覆盖引用的本地副本而不会影响引用同一对象的其他变量(毕竟,很可能没有这样的变量!),但成员或项目赋值(例如array = [])基本上是方法调用,修改对象。

通常,从现有的列表生成新列表的最简单方法是使用列表推导,其中某些修改模式应用于每个元素,并且可选地进行一些过滤。在此示例中为new_array[i] = ...

答案 2 :(得分:1)

在第三行,您将y设置为x。

new_array = array

答案 3 :(得分:0)

这一行至关重要:

new_array = array

您必须将new_array视为新变量,而不是变量(对象)的新名称,其名称为array