如何避免链接列表中的对象?

How to avoid linking of objects in a list?

我的问题很简单,但我无法解决。当我将对象插入列表时,每当我更改其中一个时,列表的元素都会发生变化(我认为它们都指向内存中的同一个对象)。我想取消它们的链接,这样列表就不会充满具有相同值的完全相同的对象。例如。避免链接或可变性。我认为问题是我如何初始化对象,但我不确定如何解决它。这是我的代码。

from typing import List, Tuple

class State:
    #think of State as some kind of coordinates
    def __init__(self, z:float, angle:float):
        self.z = z
        self.angle = angle

class ListOfStates:
    #this should be an object with a list containing DIFFERENT (unlinked) State objects
    def __init__(self, list_of_states : List[State]):
        self.list_of_states = list_of_states

class StateSettings:
    #a bigger object to encapsulate previous objects
    def __init__(self, state : State, list_of_states : ListOfStates):
        self.state = state
        self.list_of_states = list_of_states
some_number = 42

# my try #1
state_settings = StateSettings
#create a list of State objects to be used later
state_settings.list_of_states = [State for i in range(some_number)]
state_settings.state = State
for i in range(some_number):
    state_settings.list_of_states[i].angle = i

并且state_settings.list_of_states包含对象的相同副本42次,例如

print(state_settings.list_of_states[0].angle)
print(state_settings.list_of_states[1].angle)
print(state_settings.list_of_states[2].angle)

打印

41
41
41

我也尝试了不同的初始化方法,但没有成功。

# my try #2
state_settings = StateSettings(
    state = State(
        z = 0,
        angle = 0),
    list_of_states = [State for i in range(some_number)]
)
for i in range(some_number):
    state_settings.list_of_states[i].angle = i

# my try 3
from copy import deepcopy
state_settings = StateSettings
state_settings.list_of_states = [deepcopy(State) for i in range(some_number)]
state_settings.state = deepcopy(State)
for i in range(some_number):
    state_settings.list_of_states[i].angle = i

我的问题,据我所知, or List of Objects changes when the object that was input in the append() function changes.

等答案并没有解决

您在代码中犯了一些基本错误。让我先尝试用您的代码行来阐明这些内容

# my try #1
state_settings = StateSettings

您在上一行所做的是,您将 class StateSettings 分配给 state_settings 变量。您从未在此处创建对象。

#create a list of State objects to be used later
state_settings.list_of_states = [State for i in range(some_number)]

你在这里做的也是一样的,创建了一个 State class 引用的列表,而不是对象。所以,列表中的所有值都是相同的。

state_settings.state = State

您在这里所做的是将属性状态设置为 StateSettings class,而不是对象。

for i in range(some_number):
    state_settings.list_of_states[i].angle = i

你在这里做了什么,设置了 class 状态的属性角度。由于列表中的所有值都是相同的 State 引用,因此所有值都将相同

综上所述,

When you assign an attribute to the class name, attribute gets added to the class itself. Any where you have a reference to that class will have the same attribute value. When you create an object and then set an attribute on the object, the attribute lies only in that object. Its not reflected on other objects created.

下面是对您编写的代码的简单更新,我想它可以像您想要的那样工作。

from typing import List


class State:
    # think of State as some kind of coordinates
    # Use default values, so you dont need to provide a value in init
    def __init__(self, z: float = None, angle: float = None):
        self.z = z
        self.angle = angle


class ListOfStates:
    # this should be an object with a list containing DIFFERENT (unlinked) State objects
    # Use default values, so you dont need to provide a value in init
    def __init__(self, list_of_states: List[State] = None):
        self.list_of_states = list_of_states


class StateSettings:
    # a bigger object to encapsulate previous objects
    # Use default values, so you dont need to provide a value in init
    def __init__(self, state: State = None, list_of_states: ListOfStates = None):
        self.state = state
        self.list_of_states = list_of_states


some_number = 42

# my try #1
state_settings = StateSettings()
# create a list of State objects to be used later
state_settings.list_of_states = [State() for i in range(some_number)]
state_settings.state = State()
for i in range(some_number):
    state_settings.list_of_states[i].angle = i