两个实例引用同一个对象问题

Two instances referring to the same object problem

我有 TestData class 我想存储 time, x, y 信息的地方。

然后我有一个 GenericData class,我想要两个 TestData 实例保存为 leftright.

我实例化了GenericData并且我在左边的实例上附加了一个值,但是右边的实例也被更新了!

这意味着当我调用 generic = GenericData(TestData(), TestData()) 时,两个 TestData() 调用正在实例化同一个对象。

如何在 GenericData 中实例化两个不同的 TestData,以便我可以独立更新它们?

class GenericData:
    def __init__(self, left, right):
        self.left = left
        self.right = right

class TestData:
    def __init__(self, t=[], x=[], y=[]):
        self.t = t
        self.x = x
        self.y = y

generic = GenericData(TestData(), TestData())
generic.left.t.append(3)

print(generic.left.t)
print(generic.right.t)

[3]
[3]    <-- This one should be empty!

改变这个

class TestData:
    def __init__(self, t=[], x=[], y=[]):
        self.t = t
        self.x = x
        self.y = y

至此

class TestData:
    def __init__(self, t=None, x=None, y=None):
        if t is None:
            t = []
        if x is None:
            x = []
        if y is None:
            y = []
        self.t = t
        self.x = x
        self.y = y

通常,当我们使用列表或字典作为函数的默认参数时,我们希望程序在每次调用该函数时都创建一个新的列表或字典。然而,这不是 Python 所做的。第一次调用该函数时,Python 会为列表或字典创建一个持久对象,因为 Python 中的函数是 first-class 对象。以后每次调用该函数时,Python 都会使用第一次调用该函数时创建的同一持久对象。

参考:https://effbot.org/zone/default-values.htm

GenericDataleftright 成员是两个不同的对象,但它们共享在 TestData 定义中作为默认参数创建的相同列表实例。

In [4]: id(generic.right) == id(generic.left)
Out[4]: False
In [5]: id(generic.right.t) == id(generic.left.t)
Out[5]: True

因此你应该避免可变的默认参数。