我有一个python的小问题。我找到了一种绕过它的方法,但仍然,它让我感到烦恼......采取以下代码,我尝试将问题重写为最简单的形式:
"WE DEFINE A SIMPLE OBJET"
class Object():
def __init__(self,argument):
self.table = argument
"We define an array that will be used as the argument for the 'Object' instances"
tab = [0,0]
"We instanciate 2 'Object' using the 'tab' array as an argument"
Obj1=Object(tab)
Obj2=Object(tab)
"We change the first value of the first Object's table to 1"
Obj1.table[0] = 1
"RESULTS (we are expecting the first Object's tab to be [1,0] and the second to be [0,0] but we get [1,0] for both)"
print(Obj1.table)
print(Obj2.table)
出:
>>[1,0]
>>[1,0]
似乎不是使用'tab'值创建对象self.table变量,而是通过引用将self.table链接到tab变量。因此,当我们尝试修改两个对象之一中的self.table变量时,它也会在所有其他实例中进行修改。这是正常的吗?我的代码有问题吗?
有关信息,我通过将第4行更改为:
self.table = [argument[x] for x in range(len(argument))]
谢谢!! :)
PS:我不知道是否有任何链接,但这种其他行为也困扰着我。也许根本原因是一样的:
在:
a = [[0,0]]*2
a[0][0] = 1
print(a)
出:
>> [[1, 0], [1, 0]]
这是一个意想不到的结果,而
在:
a = [[0,0] for x in range(2)]
a[0][0] = 1
print(a)
出:
>> [[1, 0], [0, 0]]
给出了预期的结果..:p
从Python文档:
Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定。对于可变或包含可变项的集合,有时需要一个副本,因此可以更改一个副本而不更改另一个副本。
对于复制对象,有一个特殊的模块可以完成工作。 Python copy module
当您进行分配时,例如您在此示例中的内容,您不是创建新对象,而是创建对象的引用。另一种方法是根据https://docs.python.org/2/library/copy.html进行深度复制,但是IMO这是非常hacky。
我如何避免这方面的问题是尝试使我的程序尽可能不可变,这意味着我不想重新分配变量或更改现有变量。相反,您尝试保留对象状态并根据其他对象的内容创建新对象。