在Python中评估为相等的非等效变量

时间:2014-03-23 15:26:00

标签: python class oop variables equality

因此,在测试一些代码时,我发现Python中有一些奇怪的功能,即两个不同值的变量评估为相等。产生上述行为的代码如下

class Foo:
    def __init__(self):
        self.x = [1,2,3]
        self.y = self.x

    def ChangeX(self):
        self.x.append(4)

    def equals(self):
        print(self.x==self.y)

当我运行此代码时,变量会按原样初始化。如果我跑

f = Foo()
f.equals()

输出为True,我可以理解,因为此时f.x和f.y都保持相同的值。但是,当我跑

r = Foo()
r.ChangeX()
r.equals()

输出仍然是真的。这让我很困惑。 r.x和r.y显然不再保持相同的值(按顺序打印它们甚至提供不同的输出),但Python似乎相信这两个变量彼此相等。

我有一种预感,这与我正在使用课程这一事实有关;但我仍然不知道这里究竟发生了什么,或者如何“修复”它。谁能解释一下?

4 个答案:

答案 0 :(得分:3)

self.xself.y都在内存中引用相同的列表对象。这意味着,当您更新一个时,另一个将反映更改。

您可以在以下演示中看到此行为:

>>> a = [1, 2, 3]
>>> b = a
>>>
>>> # The contents of a and b are the same
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]
>>>
>>> # And their ids are the same
>>> id(a)
33908856
>>> id(b)
33908856
>>>
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]
>>>

如果您想更改此行为,可以将self.y分配给self.x的浅表副本:

self.y = self.x[:]

参见下面的演示:

>>> a = [1,2,3]
>>> b = a[:]
>>>
>>> # The contents of a and b are the same
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]
>>>
>>> # But their ids are different
>>> id(a)
33984680
>>> id(b)
33984960
>>>
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3]
>>>

答案 1 :(得分:2)

您没有两个列表。您有一个列表x以及一个名为list x的列表y的引用。修改列表x时,也会修改引用y后面的值。详细了解此here

答案 2 :(得分:1)

self.xself.y引用相同的数据。当你这样做

self.y = self.x

将两个变量绑定到内存中的同一个数组。

如果您希望它们与众不同,最好这样做

self.y = list(self.x)

答案 3 :(得分:0)

正如您所看到的,self.y = self.x只是将y分配给x

class Foo:
    def __init__(self):
        self.x = [1,2,3]
        self.y = self.x

    def ChangeX(self):
        self.x.append(4)

    def equals(self):
        print(self.x==self.y)


f = Foo()
f.equals()
f.ChangeX()
f.equals()
print(f.x)
print(f.y)
#True
#True
#[1, 2, 3, 4]
#[1, 2, 3, 4]