I've got a one type of object, data_entry
, that has a 2-dimensional array of other objects, time_entry
.
Initialization of time_entries the array within data_entry
looks like this:
[([time_entry()] * 12) for i in range(5)]
and initialization of the data_entry
looks like this:
thing = data_entry()
Now, I have a list of "things", each which contains it's own 2d array of time_entry
s.
Each time_entry
has a list as one of it's attributes, initialized like so:
attributes = []
I modify attributes by extending it using .extend()
.
However, the problem I run into when I do this is EVERY single time_entry
object in EVERY single data_entry
object gets extended.
I know problems like this can arise from improper initialization of objects, so I'm wondering if perhaps my object creations are poor or there is another python quirk I am unaware of.
If you are performing the initialization on the class, it will affect all instances of the class. If that’s the case, this is not a result of it being in a list, but of it being on the class. For example:
#!/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
You will see that both Fred and Wilma are thin, smart, fat, and stupid.
Wilma: ['thin', 'smart', 'fat', 'stupid']
Fred: ['thin', 'smart', 'fat', 'stupid']
One way to fix this is to put the attribute creation into the init method, so that the attribute is per-instance:
class BedrockDenizen():
def __init__(self):
self.attributes = []
With that change, only Wilma is thin and smart, and only Fred is fat and stupid.
Wilma: ['thin', 'smart']
Fred: ['fat', 'stupid']
You may also need to show us more code. @Bakuriu notes that the problem may be that you are only creating one instance, and he may be right. For example, if this is closer to your code:
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
Then Fred and Wilma will continue to have the same attributes, because they aren’t really separate people. You may wish to use code more like this:
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
That depends on what your needs are, though, as it seems like an odd way of doing things without more info.