我有一个单一类型的对象,
data_entry
,它具有其他对象的二维数组,time_entry
。
time_entries
data_entry
内数组的初始化如下所示:
[([time_entry()] * 12) for i in range(5)]
data_entry
的初始化如下所示:
thing = data_entry()
现在,我有一个“事物”列表,每个事物都包含它自己的
time_entry
二维数组。
每个
time_entry
都有一个列表作为其属性之一,初始化如下:
attributes = []
我通过使用
.extend()
扩展属性来修改属性。
但是,当我这样做时遇到的问题是每个
time_entry
对象中的每个 data_entry
对象都会被扩展。
我知道这样的问题可能是由于对象初始化不当而引起的,所以我想知道是否我的对象创建很差或者还有另一个我不知道的Python怪癖。
如果对类执行初始化,它将影响该类的所有实例。如果是这样的话,这不是它在列表中的结果,而是它在类中的结果。例如:
#!/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
你会发现 Fred 和 Wilma 都瘦、聪明、胖、笨。
Wilma:[‘瘦’、‘聪明’、‘胖’、‘笨’]
弗雷德:[‘瘦’、‘聪明’、‘胖’、‘愚蠢’]
解决此问题的一种方法是将属性创建放入 init 方法中,以便该属性是针对每个实例的:
class BedrockDenizen():
def __init__(self):
self.attributes = []
有了这个变化,只有威尔玛又瘦又聪明,只有弗雷德又胖又笨。
Wilma:[‘瘦’、‘聪明’]
弗雷德:[‘胖子’、‘愚蠢’]
您可能还需要向我们展示更多代码。 @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
那么 Fred 和 Wilma 将继续具有相同的属性,因为他们并不是真正独立的人。您可能希望使用更像这样的代码:
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
但这取决于您的需求,因为如果没有更多信息,这似乎是一种奇怪的做事方式。
这听起来像是你的属性都指向内部同一个列表对象。然后你每次都在同一个对象上调用extend并修改它。
这是一个常见问题,讨论于 https://docs.python.org/3/faq/programming.html#how-do-i-create-a-multiDimension-list 和 Python 列表追加行为