Python命名元组列表,替换属性

Python命名元组列表,替换属性,python,list,namedtuple,Python,List,Namedtuple,下面是一些简化的代码,我不明白为什么它不起作用 from collections import namedtuple MyStruct = namedtuple('MyStruct', 'ThreadInstance ThreadName Mnemonic IpAddr IpGW Status Mode') Node = MyStruct(None, '', '', '', '', -1, 0) NodeDb = [] for id in range(4): NodeDb.appe

下面是一些简化的代码,我不明白为什么它不起作用

from collections import namedtuple

MyStruct = namedtuple('MyStruct', 'ThreadInstance ThreadName Mnemonic IpAddr IpGW Status Mode')

Node = MyStruct(None, '', '', '', '',  -1, 0)
NodeDb = []
for id in range(4):
    NodeDb.append(Node)

NodeDb[2]._replace(ThreadName='T2')
NodeDb[2]._replace(Mnemonic='ABCD')
NodeDb[2]._replace(IpAddr='192.0.1.2')
NodeDb[2]._replace(IpGW='192.0.1.3')
NodeDb[2]._replace(Status=0)
NodeDb[2]._replace(Mode=2)

print(NodeDb)
这是输出

'>>>
[MyStruct(ThreadInstance=None, ThreadName='', Mnemonic='', IpAddr='', IpGW='', Status=-1, Mode=0),
 MyStruct(ThreadInstance=None, ThreadName='', Mnemonic='', IpAddr='', IpGW='', Status=-1, Mode=0), 
 MyStruct(ThreadInstance=None, ThreadName='', Mnemonic='', IpAddr='', IpGW='', Status=-1, Mode=0), 
 MyStruct(ThreadInstance=None, ThreadName='', Mnemonic='', IpAddr='', IpGW='', Status=-1, Mode=0)]'

请记住,该列表中的每一项都像C语言中的指针一样工作。Python变量总是通过引用传递和使用。也就是说,从它的书写方式来看,这是真的:

assert NodeDb[0] is NodeDb[1] is NodeDb[2] is NodeDb[3] # True

我认为您需要一个单独对象的列表,在这种情况下,您应该在for循环中移动
Node=MyStruct(…)

\u replace
并不像您想象的那样。从:

某些名称为双。\u替换(kwargs)

返回指定元组的新实例,用新值替换指定字段:

您正在调用
\u replace
,但从未存储它返回的新
节点。它返回一个新对象而不是“就地”更改对象的原因是
namedtuples
根据定义是不可变的,也就是说,它们在创建后不能更改

请注意,您的
for
循环将创建一个包含对同一
节点的四个引用的列表。在这种情况下,这并不是一个真正的问题,因为您创建的对象都是相同的,
namedtuple
是不可变的,但通常要注意这一点

总而言之:

from collections import namedtuple

MyStruct = namedtuple('MyStruct', 'ThreadInstance ThreadName Mnemonic IpAddr IpGW Status Mode')

NodeDb = []
Node = MyStruct(None, '', '', '', '',  -1, 0)
for id in range(4):
    NodeDb.append(Node)

NodeDb[2] = NodeDb[2]._replace(ThreadName='T2',
                               Mnemonic='ABCD',
                               IpAddr='192.0.1.2',
                               IpGW='192.0.1.3',
                               Status=0,
                               Mode=2)

print(NodeDb)

你期望得到什么样的结果?-1:标题太糟糕了。没什么意义。没有帮助,非常感谢。既然您指出了_replace是一个新对象,那么它就有意义了。@scriptOmate,不客气。如果答案确实回答了您的问题,您可以将其标记为已解决:)一般来说,您是正确的,但这并不重要,因为所有对象都是相同的,它们是不可变的。事实上,创建相同(命名)元组的四个实例是一种浪费。
from collections import namedtuple

MyStruct = namedtuple('MyStruct', 'ThreadInstance ThreadName Mnemonic IpAddr IpGW Status Mode')

NodeDb = []
Node = MyStruct(None, '', '', '', '',  -1, 0)
for id in range(4):
    NodeDb.append(Node)

NodeDb[2] = NodeDb[2]._replace(ThreadName='T2',
                               Mnemonic='ABCD',
                               IpAddr='192.0.1.2',
                               IpGW='192.0.1.3',
                               Status=0,
                               Mode=2)

print(NodeDb)