这是一些简化的代码,我不明白为什么它不起作用。
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)]'
答案 0 :(得分:7)
_replace
没有按照您的想法行事。来自docs:
somenamedtuple._replace(kwargs)
返回指定元组的新实例,用新值替换指定字段:
>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)
您正在调用_replace
,但您永远不会存储它返回的新Node
。它返回一个新对象而不是改变对象“就地”的原因是namedtuples
根据定义是不可变的,即在创建它们之后它们不能被改变。
请注意,您的for
循环会创建一个包含对同一Node
的四个引用的列表。在这种情况下,这不是一个真正的问题,因为您创建的对象都是相同的,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 :(得分:1)
请记住,该列表中的每个项目都与C语言中的指针类似。 Python变量总是由引用传递和使用。也就是说,它的写法,这是真的:
assert NodeDb[0] is NodeDb[1] is NodeDb[2] is NodeDb[3] # True
我想你想要一个单独的对象列表,在这种情况下,你应该在for循环中移动Node = MyStruct(...)
。