两个实例引用同一个对象问题
Two instances referring to the same object problem
我有 TestData
class 我想存储 time, x, y
信息的地方。
然后我有一个 GenericData
class,我想要两个 TestData
实例保存为 left
和 right
.
我实例化了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 都会使用第一次调用该函数时创建的同一持久对象。
GenericData
的 left
和 right
成员是两个不同的对象,但它们共享在 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
因此你应该避免可变的默认参数。
我有 TestData
class 我想存储 time, x, y
信息的地方。
然后我有一个 GenericData
class,我想要两个 TestData
实例保存为 left
和 right
.
我实例化了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 都会使用第一次调用该函数时创建的同一持久对象。
GenericData
的 left
和 right
成员是两个不同的对象,但它们共享在 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
因此你应该避免可变的默认参数。