简体   繁体   English

在 Python 中创建对象数组

[英]Create an Array of objects in Python

I'm trying to make a list of objects in python.我正在尝试在 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".我得到输出“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.似乎 append 只是复制指向对象的指针而不是所述对象的副本。 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?如何在不使用新对象的情况下使 List 的两个元素不同?

I'm trying to make a list of objects in python.我正在尝试在 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.即使您尝试使用某种copy功能,它也只是在幕后为您创建了一个新实例。

What you can do is use a for loop to create your array.您可以做的是使用for循环来创建数组。

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.如果您不想使用for循环,您可以在将其附加到数组之前实例化一个新实例。

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.首先,你是从“object”继承而来的,不需要显式放置它,你可以把它留空。

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.您应该改用“self.variable”,并为此声明一个构造函数。

Third, you are modifying Test1.Dat1 4 times and appending the same object twice.第三,您要修改 Test1.Dat1 4 次并附加同一个对象两次。 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 :如果您绝对需要使用具有更改值的相同实例,则可以使用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.请参阅: https : //docs.python.org/2/library/copy.html以了解copy (又名浅拷贝)和deepcopy之间的差异,因为根据对象的复杂性,这可能很重要。 It also tells you how to implement __copy__ and __deepcopy__ if copying the object is nontrivial.如果复制对象很重要,它还会告诉您如何实现__copy____deepcopy__

So, TL;DR is I'd really suggest using new objects and discourage mutability, but copy is there if you need it.所以,TL;DR 是我真的建议使用新对象并阻止可变性,但如果需要, copy就在那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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