4

これは、なぜ機能しないのか理解できない単純化されたコードです。

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)]'
4

2 に答える 2

7

_replaceあなたが思っていることをしません。ドキュメントから:

somenamedtuple._replace(kwargs)

指定されたフィールドを新しい値に置き換えて、名前付きタプルの新しいインスタンスを返します。

>>> p = Point(x=11, y=22)  
>>> p._replace(x=33)  
Point(x=33, y=22)

呼び出し_replaceていますが、返された新しいものを保存することはありませんNode。オブジェクトを「その場で」変更するのではなく、新しいオブジェクトを返す理由namedtuplesは、定義上、不変であるためです。つまり、オブジェクトを作成した後に変更することはできません。

forループが同じ への 4 つの参照のリストを作成することに注意してください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)
于 2012-01-25T20:29:23.353 に答える
1

そのリストの各項目は、C 用語のポインターのように機能することに注意してください。Python 変数は常に参照によって渡され、使用されます。つまり、それが書かれている方法は、これは本当です:

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

個別のオブジェクトのリストが必要だと思います。その場合は、Node = MyStruct(...)for ループ内に移動する必要があります。

于 2012-01-25T20:22:32.767 に答える