更新变量会更新分配的类属性

时间:2015-03-23 22:06:44

标签: python

为了证明我的问题,我有以下代码:

class Base(object):

    def __init__(self):
        self._base = [1,3]

    @property
    def base(self):
        return self._base

gp = Base()

class Parent1(object):

    def __init__(self):
        self.gp = gp.base

    def appendx(self):
        self.gp.append(4)
        return self.gp

class Parent2(object):

    def __init__(self):
        self.gp = gp.base

    def appendx(self):
        self.gp.append(7)
        return self.gp

class First(Parent1, Parent2):

    def __init__(self):
        super(First, self).__init__()

class Second(Parent2, Parent1):

    def __init__(self):
        super(Second, self).__init__()


f = First()
s = Second()

# [First]
f.appendx()
print "f.gp = %s" %f.gp      # f.gp = [1, 3, 4]
print "s.gp = %s" %s.gp      # s.gp = [1, 3, 4]    

# [Second]
a = s.appendx()
print "f.gp = %s" %f.gp      # f.gp = [1, 3, 4, 7]
print "s.gp = %s" %s.gp      # s.gp = [1, 3, 4, 7]
print "a = %s" %a            # a = [1, 3, 4, 7]

# [Third]
gp.base[0] ="a"
print "f.gp = %s" %f.gp      # f.gp = ['a', 3, 4, 7]
print "s.gp = %s" %s.gp      # s.gp = ['a', 3, 4, 7]
print "a = %s" %a            # a = ['a', 3, 4, 7]

# [Fourth] Confused from here on
a[0] ="b"
print "f.gp = %s" %f.gp      # f.gp = ['b', 3, 4, 7]
print "s.gp = %s" %s.gp      # s.gp = ['b', 3, 4, 7]
print "a = %s" %a            # a = ['b', 3, 4, 7]
print "type(a) = %s" %type(a) # type(a) = <type 'list'>

我可以围绕前三个部分,但我不明白,为什么更新列表会更新其他所有部分。一些解释会有所帮助。

2 个答案:

答案 0 :(得分:2)

这就是如何在python中分配引用数组的变量

a = [1, 2, 3]
b = a
b.append(4)

ab现在都是[1, 2, 3, 4]。第二行仅复制对数组的引用,但不复制数组。在程序执行self.gp = gp.base时,以及在返回对数组的引用的所有位置,都会发生同样的情况。你的程序中只有一个数组。

如果您不希望所有对象共享同一个数组,则必须以某种方式复制数组。如果您想使用浅或深拷贝,这取决于您。 How to clone or copy a list?有一个很长的解释。

答案 1 :(得分:1)

描述发生此错误的原因。

a = [1]
b = a
>>>print id(a), id(b)
3072113580 3072113580

同时,ab都引用同一个对象。如果对任何列表进行修改会导致每个引用variables

要克服这个问题:

a = [1]
b = a[:] # copy list a to b
>>>print a, b
3053445164 3053960492

希望这有帮助