简体   繁体   中英

Create an Array of objects in Python

I'm trying to make a list of objects in python. I'm doing this by making one object and appending it. Here is my code.

#Creating a Python object
class TestDat(object):
     Dat1 = None
     Dat2 = None
#Declaring the Test Array
TestArray = []
#Declaring the object
Test1 = TestDat()
#Defining the member variables in said object
Test1.Dat1 = 0
Test1.Dat1 = 1
#Appending the object to the List
TestArray.append(Test1)
#Rewriting and appending again
Test1.Dat1 = 3
Test1.Dat1 = 4
TestArray.append(Test1)
#Printing our Our Results
print TestArray[0].Dat1
print TestArray[1].Dat1

When I test it out. I get the output "4 4". This means that both elements of the list are the same. It seems like append is just copying a pointer to the object instead of a copy of said object. I would eventually like to do this in a loop so I can't be doing that. How can I get both elements of the List to be different without using a new object?

I'm trying to make a list of objects in python. I'm doing this by making one object

You simply can't do this; your second statement contradicts your first statement. You must instantiate as many objects as you wish to have, end of story. Even if you try to use some kind of copy function, it is just creating a new instance for you under the hood.

What you can do is use a for loop to create your array.

testArray = []
for i in range(10):
    testDat = TestDat(dat1=i, dat2=i*2)
    testArray.append(testDat)

If you don't want to use a for loop, you can just instantiate a new instance before appending it to the array.

testArray = []
testDat = TestDat(dat1=1, dat2=2)
testArray.append(testDat)
testDat = TestDat(dat1=3, dat2=4) # re-assigns the variable to the new instance
testArray.append(testDat)

If you have an existing list of items from which you are creating this array of objects, the best thing you can do is use a list comprehension to build your new list. For instance, if you had an array of tuples:

myOriginalData = [(1,2), (3,4), (5,6)]
myNewList = [TestDat(dat1=x, dat2=y) for (x,y) in myOriginalData]

There are several mistakes here:

First, you have inherited from "object" and there is no need to explicitly put it, you can leave it empty.

Second, the way you declared your variables in your class makes the class share the same values across all instances, thats why you get the latest modified values always. you should use "self.variable" instead, and declare a constructor function for that.

Third, you are modifying Test1.Dat1 4 times and appending the same object twice. thats why you get the same object every time.

this is the right way:

class TestDat():          # leave this empty
    def __init__(self):   # constructor function using self
        self.Dat1 = None  # variable using self.
        self.Dat2 = None  # variable using self
    
TestArray = [] #empty array

Test1 = TestDat() #this is an object
Test2 = TestDat() #this is another object
        
Test1.Dat1 = 0 #assigning value to object 1 
Test1.Dat2 = 1 #assigning value to object 1 
    
Test2.Dat1 = 3 #assigning value to object 2 
Test2.Dat2 = 4 #assigning value to object 2

TestArray.append(Test1) #append object 1
TestArray.append(Test2) #append object 2 
    
print (TestArray[0].Dat1) # this is Test1
print (TestArray[1].Dat1) # this is Test2

or even simpler:

class TestDat():
    def __init__(self, Dat1, Dat2):
        self.Dat1 = Dat1
        self.Dat2 = Dat2

TestArray = [TestDat(0,1),
             TestDat(3,4)]

print (TestArray[0].Dat1) # this is Test1
print (TestArray[1].Dat1) # this is Test2

or this way:

class TestDat():
    def __init__(self):
        self.Dat1 = None
        self.Dat2 = None
    
TestArray = [] #empty array
size = 2       #number of loops

for x in range(size):  # appending empty objects
    TestArray.append(TestDat())

#initialize later
TestArray[0].Dat1 = 0
TestArray[0].Dat2 = 1

TestArray[1].Dat1 = 3
TestArray[1].Dat2 = 4

print("print everithing")
for x in range(len(TestArray)):
    print("object "+str(x))
    print(TestArray[x].Dat1)
    print(TestArray[x].Dat2)

You're right, when you add objects it does add them by reference.

There's a couple ways to do this. Probably the cleanest is just to make a new object for each entry. If you absolutely need to use the same instances with changed values, you can use copy.copy :

from copy import copy
...
# Set up object
TestArray.append(copy(test1))
# Change stuff
TestArray.append(copy(test2))

See: https://docs.python.org/2/library/copy.html for the differences between copy (aka shallow copy) and deepcopy , as it may be important depending on the complexity of your object. It also tells you how to implement __copy__ and __deepcopy__ if copying the object is nontrivial.

So, TL;DR is I'd really suggest using new objects and discourage mutability, but copy is there if you need it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM