Python:更改对象数组中的单个对象会改变所有对象,即使在不同的数组中也是如此

时间:2016-07-05 16:10:51

标签: python arrays object

我有一种类型的对象data_entry,它有一个其他对象的二维数组,time_entry

初始化time_entries data_entry中的数组如下所示:

[([time_entry()] * 12) for i in range(5)]

data_entry的初始化如下所示:

thing = data_entry()

现在,我有一个""的列表,每个包含它自己的time_entry的2d数组。

每个time_entry都有一个列表作为其中一个属性,初始化如下:

attributes = []

我通过使用.extend()扩展属性来修改属性。

但是,我在执行此操作时遇到的问题是每个time_entry对象中的每个data_entry对象都会被扩展。

我知道这样的问题可能是因为对象的初始化不正确而引起的,所以我想知道我的对象创作是否很差或者是否有另一个我不知道的python怪癖。

2 个答案:

答案 0 :(得分:1)

这听起来像你的属性都指向同一个列表对象里面。然后每次都在同一个对象上调用extend并进行修改。

这是一个常见问题,并在以下讨论 https://docs.python.org/3/faq/programming.html#how-do-i-create-a-multidimensional-listPython list append behavior

答案 1 :(得分:1)

如果要对类执行初始化,则会影响该类的所有实例。如果是这种情况,这不是因为它在列表中,而是在列表中。例如:

#!/usr/bin/python

class BedrockDenizen():
    attributes = []


wilma = BedrockDenizen()
fred = BedrockDenizen()

wilma.attributes.extend(['thin', 'smart'])
fred.attributes.extend(['fat', 'stupid'])

print 'Wilma:', wilma.attributes
print 'Fred:', fred.attributes

你会看到弗雷德和威尔玛都很瘦,聪明,肥胖,愚蠢。

  威尔玛:['瘦','聪明','胖','愚蠢']

     弗雷德:['瘦','聪明','胖','愚蠢']

解决此问题的一种方法是将属性创建放入 init 方法,以便属性为每个实例:

class BedrockDenizen():
    def __init__(self):
        self.attributes = []

随着这种变化,只有威尔玛瘦弱而聪明,只有弗雷德才是胖子和傻瓜。

  威尔玛:['瘦','聪明']

     弗雷德:['胖','愚蠢']

您可能还需要向我们展示更多代码。 @Bakuriu指出,问题可能是你只创建了一个实例,而他可能是对的。例如,如果这更接近您的代码:

class BedrockDenizen():
    def __init__(self):
        self.attributes = []

neighborhood = [([BedrockDenizen()] * 2) for i in range(2)]

flintstones, rubbles = neighborhood
fred, wilma = flintstones

wilma.attributes.extend(['thin', 'smart'])
fred.attributes.extend(['fat', 'stupid'])

print 'Wilma:', wilma.attributes
print 'Fred:', fred.attributes
然后弗雷德和威尔玛将继续拥有相同的属性,因为他们并不是真正独立的人。您可能希望使用更像这样的代码:

class BedrockDenizen():
    def __init__(self):
        self.attributes = []

neighborhood = [[BedrockDenizen() for n in range(2)] for i in range(2)]

flintstones, rubbles = neighborhood
fred, wilma = flintstones

wilma.attributes.extend(['thin', 'smart'])
fred.attributes.extend(['fat', 'stupid'])

print 'Wilma:', wilma.attributes
print 'Fred:', fred.attributes

这取决于你的需求,因为在没有更多信息的情况下做事情似乎很奇怪。