Python中变量更新导致类属性更新问题

在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'>

这段代码首先创建了一个名为Base的类,该类有一个名为base的私有属性。Base类有两个子类:Parent1Parent2Parent1Parent2类都有一个名为gp的属性,该属性的值是gp.base

然后,代码创建了一个名为First的类,该类继承自Parent1Parent2。同样,First类也有一个名为gp的属性,其值是gp.base

最后,代码创建了一个名为Second的类,该类也继承自Parent2Parent1Second类同样有一个名为gp的属性,其值也是gp.base

当调用f.appendx()方法时,它会将4添加到f.gp列表中。由于f.gps.gp都引用相同的列表,因此s.gp也会被更新。

当调用s.appendx()方法时,它会将7添加到s.gp列表中。由于f.gps.gp都引用相同的列表,因此f.gp也会被更新。

当调用gp.base[0] = "a"时,它会将gp.base列表的第一个元素改为"a"。由于f.gps.gp都引用相同的列表,因此f.gps.gp也会被更新。

当调用a[0] = "b"时,它会将a列表的第一个元素改为"b"。由于f.gps.gpa都引用相同的列表,因此f.gps.gpa都会被更新。

2、解决方案

为了解决这个问题,需要对列表进行浅拷贝或深拷贝。浅拷贝只复制列表的引用,而深拷贝则复制列表中的所有元素。

要进行浅拷贝,可以使用list()函数。例如:

a = [1, 2, 3]
b = a[:]

在这个例子中,ba的浅拷贝。这意味着ba引用相同的列表。

要进行深拷贝,可以使用copy.deepcopy()函数。例如:

import copy

a = [1, 2, 3]
b = copy.deepcopy(a)

在这个例子中,ba的深拷贝。这意味着ba引用不同的列表。

通过使用浅拷贝或深拷贝,可以防止对一个列表的更新影响到其他列表。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值