英文:
Python: List of objects can't be modified individually due to undefined list size (?)
问题
我正在设置一个家庭传感器网络,我有多个“节点”(Arduino位置),每个节点有多个要报告的数据点。因此,我将所有节点(节点对象)存储在一个列表中,每个节点对象都有一个数据点对象列表。我的问题是,我似乎无法将数据点分配给单个节点,而是将其分配给节点列表中的所有节点。
类数据点:
名称 = ""
节点编号 = 0
节点数组索引 = 0
活动 = 假
记录下一个 = 假
def __init__(self, 名称):
self.name = 名称
类节点:
地址 = [0]*8
名称 = " "
现在消息 = 假
数据点 = []
def __init__(self, 名称 ):
self.name = 名称
节点列表 = []
node_list.append(node("花园"))
node_list.append(node("厨房"))
node_list[0].datapoints.append(datapoint("湿度"))
node_list[1].datapoints.append(datapoint("温度"))
对于我在范围(0,len(node_list[1].datapoints))中的范围:
打印(node_list[1].datapoints[i].name)
这将返回
湿度
温度
我本来希望它只返回温度,因为只有温度分配给node_list[1].datapoints
。如果我尝试首先创建对象然后将它们附加到列表,我会得到相同的结果。感谢任何帮助。
英文:
I'm setting up a home sensor network and I have multiple "nodes" (Arduino locations) and each node has several datapoints to report. So I'm storing all my nodes (node objects) in a list and each node object has a list of datapoint objects. My problem is that I can't seem to assign datapoints to individual nodes and they are instead assigned to all nodes in the node list.
class datapoint:
name = ""
node_number = 0
node_array_index = 0
active = False
log_next = False
def __init__(self, name):
self.name = name
class node:
address = [0]*8
name = " "
message_now = False
datapoints = []
def __init__(self, name ):
self.name = name
node_list = []
node_list.append(node("Garden"))
node_list.append(node("Kitchen"))
node_list[0].datapoints.append(datapoint("Humidity"))
node_list[1].datapoints.append(datapoint("Temperature"))
for i in range(0,len(node_list[1].datapoints)):
print(node_list[1].datapoints[i].name)
This returns
Humidity
Temperature
I would have expected this to return Temperature because only Temperature was assigned to node_list[1].datapoints. If I try creating objects first and appending them to the list I get the same result.
Thanks for any help.
答案1
得分: 1
尝试在__init__
函数内初始化所有类级别的变量。类似以下的方式应该有所帮助:
class datapoint:
def __init__(self, name, node_number=0, node_array_index=0, active=False, log_next=False):
self.name = name
self.node_number = node_number
self.node_array_index = node_array_index
self.active = active
self.log_next = log_next
class node:
def __init__(self, name):
self.name = name
self.address = [0]*8
self.message_now = False
self.datapoints = []
英文:
Try initializing all the class-level variables inside the __init__
functions. Something like this should help:
class datapoint:
def __init__(self, name, node_number=0, node_array_index=0, active=False, log_next=False):
self.name = name
self.node_number = node_number
self.node_array_index = node_array_index
self.active = active
self.log_next = log_next
class node:
def __init__(self, name):
self.name = name
self.address = [0]*8
self.message_now = False
self.datapoints = []
答案2
得分: 0
我认为这可能是因为你声明每个类的属性的方式有点不符合Python的风格。我说"不符合Python风格"是因为你没有使用"self.[变量名]"来初始化变量,而是像在类外部初始化变量一样。
对我来说,"datapoints" 列表在不同的 "node" 对象之间共享数值。所以,你在 node_list[0] 中将 "datapoint('Humidity')" 添加到 "datapoints" 列表中,然后在 node_list[1] 中将 "datapoint('Temperature')" 添加到 "datapoints" 列表中。然而,因为 "datapoints" 列表只有一个对象,不同类的实例之间共享这个对象的值。所以,"datapoints" 列表的值现在是 [datapoint('Temperature'), datapoint('Humidity')]。如果你想要修复这个问题,只需将其初始化为 "self.datapoints = []" 而不是 "datapoints = []"。应该像这样:
class node:
address = [0]*8
name = " "
message_now = False
def __init__(self, name ):
self.name = name
self.datapoints = []
请注意,如果你想要在将来的操作中使用 "address"、"name" 和 "message_now" 变量,当你只想让这些值针对每个 "node" 对象的实例具体化时,你将遇到类似的错误。
另外,值得注意的是,为你的变量使用更少歧义的名称可能会有所帮助。在查找这个问题时,有点难(至少对我来说,你可能不同)跟踪我正在引用的确切对象。传统的Python命名规则强烈建议将类的名称大写(因此将 "class datapoint" 更改为 "class Datapoint")。此外,通过将它们改为 "Datapoint" 和 "datapoints_list" 而不是 "datapoint" 和 "datapoints",可能有助于区分它们。这只是有助于可读性的简单建议,当然都归结为个人偏好,但这应该有助于长期调试和重新阅读代码。
希望这有所帮助,请让我知道是否还有其他需要澄清的事情或者是否有我忽略的细微差别。祝你的家庭项目顺利!
英文:
I believe it may be because of the "un-pythonic" method of declaring attributes of each of your classes. I say "un-pythonic" in that you do not initialize variables using "self.[variable_name]" and instead just initialize variables how you normally would if it were to be outside of a class.
It seems to me that the "datapoints" list is sharing values between the different "node" objects. So, you append "datapoint('Humidity')" to the "datapoints" list in node_list[0], and then you append "datapoint('Temperature')" to the "datapoints" list in node_list[1]. However, because there is only 1 object for the "datapoints" list, the value of this object is shared between different instances of the classes. So, the value of the "datapoints" list is now [datapoint('Temperature'), datapoint('Humidity')]. If you wish to fix this, simply initialize this as "self.datapoints = [ ]" instead of "datapoints = [ ]". It should look something like this:
class node:
address = [0]*8
name = " "
message_now = False
def __init__(self, name ):
self.name = name
self.datapoints = []
Note that if you wish to perform future operations with the "address", "name", and "message_now" variables, you will run into similar errors of different "node" class objects sharing values with one another when you only meant the values to be specific to each instance of the "node" object.
As a sidenote, it may be worth looking into having less ambiguous names for your variables. While looking into this issue, it was a bit difficult (at least for me, you may be different) to keep track of what exact objects I was referring back to. Conventional Python naming rules highly recommends having the names of classes be capitalized (thus changing "class datapoint" to "class Datapoint"). Furthermore, it may be worth differentiating between "datapoint" and "datapoints" by having them instead be "Datapoint" and "datapoints_list" respectively. This simply helps with readability and is of course all down to personal preference, but this should help with debugging and rereading code in the long run.
I hope this helps, please let me know if there's anything else I should clarify or if there are any nuances that I overlooked. Best of luck with your home project!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论