【问题标题】:How to avoid linking of objects in a list?如何避免链接列表中的对象?
【发布时间】:2021-12-27 09:44:41
【问题描述】:

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

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

据我所知,Changing a single object within an array of objects changes all, even in a different arrayList of Objects changes when the object that was input in the append() function changes 之类的答案无法解决我的问题。

【问题讨论】:

  • [State() for i in range(some_number)]注意括号,你需要真正创建对象
  • 感谢您的评论,但如果不向 State 提供参数,我无法执行 State()。 (缺少必需的位置参数“z”和“角度”)。我想避免在这一步计算“z”和“角度”——我只想添加“角度”。
  • 在这种情况下,为构造函数添加一个默认的None 值:__init__(self, z:float = None, angle:float = None)
  • 哇,我没想到这一点,谢谢亚历克斯!随意正式回答这个问题。否则我会在几个小时内回复并指出您的评论。

标签: python list object memory mutability


【解决方案1】:

您在代码中犯了一些基本错误。让我试着先用你的代码行来说明一下这些

# my try #1
state_settings = StateSettings

您在上面的行中所做的是,您将 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 类引用列表,而不是对象。因此,列表中的所有值都是相同的。

state_settings.state = State

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

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

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

总结上述问题,

当您将属性分配给类名时,属性会添加到类本身。任何引用该类的地方都将具有相同的属性值。 当您创建一个对象然后在该对象上设置一个属性时,该属性只存在于该对象中。它不会反映在创建的其他对象上。

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

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

【讨论】:

    猜你喜欢
    • 2012-03-22
    • 2014-02-27
    • 1970-01-01
    • 2022-11-02
    • 2021-08-13
    • 2011-02-10
    • 1970-01-01
    • 2015-07-30
    • 1970-01-01
    相关资源
    最近更新 更多